异步通信服务器端代码.docx
- 文档编号:3871674
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:19
- 大小:24.57KB
异步通信服务器端代码.docx
《异步通信服务器端代码.docx》由会员分享,可在线阅读,更多相关《异步通信服务器端代码.docx(19页珍藏版)》请在冰点文库上搜索。
异步通信服务器端代码
1.需要能够实现多个工作站互相进行异步数据传输
2.能够根据不同工作站的配置情况选择从哪个工作站申请数据
3.能够及时收获各工作站的配置变更和在线情况
4.收到的数据信息量较大,需要进行处理后送到其他模块备用。
根据这些需求让我觉得我要做的这部分程序有点像QQ的功能,因此我需要在服务器端程序建立一个服务程序。
各工作站通过服务程序获得其他工作站的在线列表和每个工作站的配置信息,所有工作站的配置一旦更新,全部上传到服务器端保留。
在这里就不讨论如何做服务程序了,这个太简单了,大家可以在网上搜到一堆例程。
服务程序代码如下:
客户端代码将在下一篇接进行介绍
Code
Imports System.ServiceProcess
Imports System.Net.Sockets
Imports System.Net
Imports System.Threading
Imports System.Collections
Imports System.Text
Imports System.IO
Public Class Server
Inherits System.ServiceProcess.ServiceBase
#Region "全局变量"
Dim ServerSocket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Dim ipep As IPEndPoint = New IPEndPoint(IPAddress.Any, 11000)
Dim htUserList As New Hashtable '用来保存在线用户和用户的"IP和端口"
Dim userName(0) As String
Dim userIPEP(0) As IPEndPoint
Dim userTime(0) As Integer
Dim DataServerInfor(0) As String
Dim DataServerSaveEnd(0) As Boolean
Dim timerDelegate As New TimerCallback(AddressOf onLineTimeOut)
Dim sw As StreamWriter
Dim movelenth As Integer = 512 '最大为512,乘以2为传送的最大字节数:
1024
Private Shared LongSendID As Integer = 0
Private LongSendMax As Integer = 50
Private dealing As Boolean = False
Private ReceiveDataList As DataQueue
#End Region
#Region "参数"
'以下是客户端到服务器端的消息开头
Const LOGININ As String = "10" '请求登陆的消息|||消息形式:
10+自己的用户名
Const LOGINOUT As String = "11" '请求登出的消息|||消息形式:
11+自己的用户名
Const GETULIST As String = "12" '请求获得在线用户列表|||消息形式:
12
Const P2PCONN As String = "13" '请求P2P连接的消息|||消息形式:
13+自己的用户名+|+对方的用户名
Const HOLDLINE As String = "14" '保持连接.|||消息开式:
14+自己的用户名
'以下是服务器到客户端的消息开头
Const HVUSER As String = "20" '用户名已存在
Const GETUSER As String = "21" '在线用户列表|||消息格式:
21+用户名+EP
Const MAKHOLD As String = "22" '打洞命令|||消息格式:
22+IP
Const LOGINOK As String = "23" '登陆成功
Const SERVCLS As String = "24" '服务器关闭
Const MSGEND As String = "25" '消息结束
Const ONEOFF As String = "26" '一个客户端下线
'以下是服务器端的命名
Const EXITPRO As String = "EXIT" '退出命令
Const SHOWULIST As String = "SHOWUSER" '显示在线用户
Const HELP As String = "HELP" '显示帮助
'以下是工作站发送给服务器的消息开头:
Const RECDEVINFO As String = "45" '工作站发送给服务器的设备配置信息
'以下是ICU客户端发送给本服务器程序的命令:
Const GETDATASERVER As String = "50" '获取当前在线的数据服务器(即工作站)
Const SHOWDATASERVER As String = "51" '将在线的数据服务器
Const GETDSERVERINFOR As String = "52" '获取某个数据服务器的配置信息
#End Region
#Region " 组件设计器生成的代码 "
Public Sub New()
MyBase.New()
' 该调用是组件设计器所必需的。
InitializeComponent()
' 在 InitializeComponent() 调用之后添加任何初始化
End Sub
'UserService 重写 dispose 以清理组件列表。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
' 进程的主入口点
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
' 在同一进程中可以运行不止一个 NT 服务。
若要将
' 另一个服务添加到此进程,请更改下行以
' 创建另一个服务对象。
例如,
'
' ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
'
ServicesToRun = New System.ServiceProcess.ServiceBase() {New Server}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
'组件设计器所必需的
Private components As System.ComponentModel.IContainer
'注意:
以下过程是组件设计器所必需的
' 可以使用组件设计器修改此过程。
' 不要使用代码编辑器修改它。
'
'Server
'
Me.ServiceName = "Cyber Service"
End Sub
#End Region
Protected Overrides Sub OnStart(ByVal args() As String)
' 在此处添加启动服务的代码。
此方法应设置具体的操作
' 以便服务可以执行它的工作。
'获得服务器的IP地址
Try
sw = New StreamWriter("C:
\log.log", True) '开启log文件
'获取第一个可用网卡作为传输用:
Dim addressList As System.Net.IPAddress() = Dns.GetHostByName(Dns.GetHostName()).AddressList
Dim ServerIP As IPAddress = addressList(0)
ServerSocket.Bind(ipep) '绑定此地址和端口
ReceiveDataList = New DataQueue
Dim listenTH As New Thread(AddressOf listen)
listenTH.Start() '启用监听的线程
WriteLog("服务器启动成功:
" & Now.ToString)
Dim timer As New Timer(timerDelegate, Nothing, 0, 5000)
Catch ex As Exception
WriteLog("OnStart:
" & Err.Description)
End Try
End Sub
Protected Overrides Sub OnStop()
' 在此处添加代码以执行停止服务所需的关闭操作。
sw.Write("服务器正常退出:
" & Now.ToString & Chr(10) & Chr(13))
sw.Flush()
sw.Close()
sw = Nothing
End Sub
'服务器监听函数
Sub listen()
While True '无限循环侦听
Try
Dim recv As Integer = 0
Dim data As [Byte]() = New Byte(1024) {}
Dim sender As New IPEndPoint(IPAddress.Any, 0)
Dim tempRemoteEP As EndPoint = CType(sender, EndPoint)
recv = ServerSocket.ReceiveFrom(data, tempRemoteEP) '从缓冲区中获取收到的信息
Dim tmpdata As New DeclearData(data, tempRemoteEP, recv) '装进信息块中
ReceiveDataList.AddItem(tmpdata) '将信息块装进本程序自己的缓冲区
If Not dealing Then
Dim dealdatathread As New Thread(AddressOf DealData)
dealdatathread.Name = "dealdata"
dealdatathread.Start()
End If
Catch e As Exception
Dim OutPutString As String = ""
OutPutString = "Error:
" & Err.Description
WriteLog(OutPutString)
OutPutString = ""
End Try
End While
End Sub
Private Sub DealData()
If Not dealing Then
dealing = True
Dim tmpdata As DeclearData
While ReceiveDataList.count > 0
Try
tmpdata = ReceiveDataList.GetFirstItem
'可以侦听到的命令:
Debug.WriteLine("收到:
" & tmpdata.datastr)
Dim msgHead As String = tmpdata.datastr.Substring(0, 2)
Select Case msgHead
Case LOGININ '登录:
userLogin(tmpdata.datastr, tmpdata.fromip)
Case LOGINOUT '注销:
userloginout(tmpdata.datastr)
Case GETULIST '获得当前在线人名单:
Dim userinfo As String = getUserList()
sendMsg(userinfo, tmpdata.fromip)
WriteLog("<" & Now.ToString & " IP:
" & tmpdata.fromip.ToString & " Ope:
获取在线人员名单>")
Case P2PCONN '向其它用户发送消息
questP2PConn(tmpdata.datastr)
Case HOLDLINE '表示该用户仍然在线
holdOnLine(tmpdata.datastr)
Case GETDATASERVER '某个客户端请求当前在线的设备列表
ShowDataServerOnLine(tmpdata.fromip)
Case RECDEVINFO '某个工作站发送来了设备的信息:
ReceiveDataServerInfor(tmpdata.datastr, tmpdata.fromip)
Case GETDSERVERINFOR
SendDeviceInforToClient(tmpdata.datastr, tmpdata.fromip)
Case Else
WriteLog("未知信息:
" & tmpdata.datastr)
End Select
Catch ex As Exception
Debug.WriteLine("错误的数据:
" & tmpdata.datastr)
Debug.WriteLine("DealData:
" & Err.Description)
WriteLog("错误的数据:
" & tmpdata.datastr)
WriteLog("DealData:
" & Err.Description)
Finally
ReceiveDataList.Remove()
End Try
End While
dealing = False
End If
End Sub
'接收到某个客户端发送的配置信息
'这个信息存放在服务器端,所有客户端从服务器端获取设备信息
'不存在多点接收的问题,因为是根据工作站来分流的
Private Sub ReceiveDataServerInfor(ByVal data As String, ByVal tempremoteep As IPEndPoint)
Dim i As Integer
Dim flag As String = data.Substring(2, 1)
Dim infodata As String = data.Substring(3, data.Length - 3)
For i = 0 To userIPEP.Length - 1
If (Not userName(i) Is Nothing) AndAlso (Not userIPEP(i) Is Nothing) AndAlso userName(i).IndexOf("DataServer") = 0 Then '是在线的工作站
If userIPEP(i).ToString.Equals(tempremoteep.ToString) Then '的确是这个工作站发送来的
If DataServerSaveEnd(i) And flag = "0" Then '判断是否为更换信息的第一波数据
DataServerSaveEnd(i) = False '以后的只能追加
DataServerInfor(i) = infodata
Else
DataServerInfor(i) &= infodata
End If
If flag = "1" Then
DataServerSaveEnd(i) = True '信息已经接收结束
SendDeviceInforToClient(i) '将这个工作站的配置信息发送给所有客户端
WriteLog("收到配置信息,来自:
" & userName(i))
End If
Exit Sub
End If
End If
Next
End Sub
'将某个工作站的配置信息发送给所有客户端
'格式:
45+登录名+|+配置信息
Private Sub SendDeviceInforToClient(ByVal index As Integer)
Try
Dim i As Integer
Dim tmpstr As String = RECDEVINFO & userName(index) & "|" & DataServerInfor(index)
For i = 0 To userName.Length - 1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 异步 通信 服务器端 代码