标题:Winsock在车间作业调度管理系统中的应用 作者:徐永新,陆宝春 作者单位:南京理工大学机械工程学院 关键字:Winsock,作业调度,VB,网络通信 摘要: 本文介绍了Winsock的基本概念及其在车间作业调度管理系统中的应用。基于Visual Basic重点讨论了一对多通信的实现方法和作业文件在网络中传输的方法,并给出了相应的VB代码。 客户端和服务器端程序如下: 客户端程序 Option Explicit '注:只列出相关变量,filepath可由用户设定 Private filepath As String Private filename As String Private filesize As Long Private dataflag As Integer '接收的数据类型标识, '1表示文件名,2表示文件长度,3表示文件内容 Private Sub Form_Load() dataflag = 1 '初始设定接收标识为文件名 tcpclient.RemoteHost = "server" '服务器名称 tcpclient.RemotePort = 1234 '服务器的侦听端口 tcpclient.Protocol = sckTCPProtocol '设置为TCP协议 tcpclient.Connect '向服务器请求连接 End Sub Private Sub cmdRequest_Click() '设备操作员点击“申请”命令按钮 On Error GoTo errorHandler If tcpclient.State <> sckClosed Then tcpclient.SendData "request" '发送申请命令 End If Exit Sub errorHandler: End Sub Private Sub tcpclient_DataArrival(ByVal bytesTotal As Long) On Error GoTo errorHandler Select Case dataflag Case 1 tcpclient.GetData filename, vbString '接收文件名 dataflag = 2 ' tcpclient.SendData "ok" '发送确认信号 Case 2 tcpclient.GetData filesize, vbLong '接收文件长度 dataflag = 3 tcpclient.SendData "ok" '发送确认信号 Case 3 Call Getfile End Select Exit Sub errorHandler: End Sub Private Sub Getfile() Static filenumber As Long '文件号 Static recnumber As Long '记录号,用于标识已接收到的数据量 Dim data() As Byte '存储文件内容的二进制动态数组 On Error GoTo errorHandler tcpclient.GetData data, vbArray + vbByte '读取接收到的数据 If recnumber = 0 Then filenumber = FreeFile If Dir(filepath & "\" & filename) <> "" Then Kill filepath & "\" & filename End If Open filepath & "\" & filename For Binary As filenumber '以二进制方式打开文件 End If recnumber = LOF(filenumber) + 1 Put filenumber, recnumber, data ' 向文件结尾处写入数据 If LOF(filenumber) = filesize Then '判断是否接收完 recnumber = 0 Close filenumber dataflag = 1 tcpclient.SendData "ok" '发送确认信号 MsgBox "文件:" & filepath & "\" & filename & "接收完毕!" End If Exit Sub errorHandler: End Sub 服务器端程序 Option Explicit '注:只列出相关变量 Private filepath As String '作业文件的路径 Private filename As String '当前队头的文件名 Private sending() As Boolean '标识发送状态的动态数组,为每一个客户设置一个发送状态 Private Sub Form_Load() tcpserver(0).Protocol = sckTCPProtocol '设置为TCP协议 tcpserver(0).LocalPort = 1234 '设置本地端口为1234 tcpserver(0).Listen '开始侦听,tcpserver(0)是专用于侦听的winsock控件 End Sub Private Sub tcpserver_ConnectionRequest(Index As Integer, ByVal requestID As Long) Dim strIp As String Dim i As Integer strIp = tcpserver(0).RemoteHostIP '获得请求连接者的IP地址 i = 1 Do While i <= tcpserver.UBound '检查是否已有该IP地址的记录 If tcpserver(i).RemoteHostIP = strIp Then '如有,则不必加载新控件 If tcpserver(i).State <> sckClosed Then tcpserver(i).Close End If tcpserver(i).LocalPort = 0 '随机分配一个端口号 tcpserver(i).Accept requestID '接受连接请求 Exit Sub End If i = i + 1 Loop ReDim sending(1 To i) '增加一个发送状态标志 Load tcpserver(i) '加载新的控件实例 tcpserver(i).LocalPort = 0 tcpserver(i).Accept requestID '用新的控件接受连接请求 End Sub Private Sub tcpserver_DataArrival(Index As Integer, ByVal bytesTotal As Long) Dim s As String tcpserver(Index).GetData s Select Case s Case "request" filename = GetHead(tcpserver(Index).RemoteHostIP) '根据申请者的IP地址返回该申请设备所对应的作业队列的队头文件名,GetHead()函数略 Sendfile Index, filename Case "ok" sending(Index) = False End Select End Sub Private Sub Sendfile(i As Integer, ByVal name As String) Static filenumber As Long Dim data() As Byte Dim size As Long On Error GoTo ErrorHandler filenumber = FreeFile Open filepath & "\" & name For Binary As filenumber '以二进制方式打开文件 size = LOF(filenumber) '取得文件长度(字节数) ReDim data(size - 1) Get filenumber, 1, data() '将文件内容全部读入data()数组中 Close filenumber sending(i) = True tcpserver(i).SendData name '发送文件名 Do While sending(i) '等待对方响应 DoEvents '处理其它事件 Loop sending(i) = True tcpserver(i).SendData size '发送文件长度 Do While sending(i) DoEvents Loop sending(i) = True tcpserver(i).SendData data '发送文件内容,如果文件比较长, '则自动分为多个数据包发送,接收方会产生多个DataArrival事件 Do While sending(i) DoEvents Loop Label1.Caption = "文件:" & filepath & "\" & name & "下发成功!" Exit Sub ErrorHandler: End Sub |