UDP协议基础: UDP(User Datagram Protocol)是一种无连接协议,与TCP操作不同,计算机间并不需要建立一个连接,同时,一个UDP应用可同时作为应用的客户或服务器方。 由于UDP协议并不需要建立一个明确的连接,因此建立UDP应用要比建立TCP应用简单得多。在TCP应用中,一个Winsock控制必须明确地设置成“监听”,而其它Winsock控制则必须使用Connect方法来初始一个连接。 使用UDP协议,在两个Winsock控制间进行数据的发送,在连接的两端必须完成以下三步: 1.设置RemoteHost属性为其它计算机的名称; 2.设置RemotePort属性为第二个Winsock控制的LocalPort属性的值; 3.申请Bind方法。 通过使用方法Bind,则可将该Winsock控制捆绑到一个本地端口,以便该Winsock控制使用该端口来进行类似TCP的“监听”功能,并防止其它应用使用该端口。 使用该协议传送数据,首先设置客户计算机的LocalPort属性。而作为服务器的计算机仅需要设置RemoteHost属性为客户计算机的IP地址或域名即可,并将其RemotePort属性设置成客户计算机上的LocalPort属性即可,然后就可通过申请SendData方法来开始信息发送,客户计算机则可在其DataArrial事件中使用方法GetData来获取发送的信息。 下例具体演示了一个“谈话”应用,以允许相互间进行实时的交谈。 UDP应用一: 建立一个新标准EXE工程文件,拖放一个Winsock控制到表单上,添加两个文本框到表单上,然后进行以下属性的设置: 表单(Form):Name=“frmPeerA” Caption=“UDP Application(1)” Winsock控制:Name=“udpPeerA” Protocol=“sckUDPProtocol” 文本框1(TextBox): Name“txtSend” 文本框2(TcxtBox): Name=“txtOutput” MultiLine-True ScrollBars=2 然后打开代码窗口,分别在相应的事件下输入以下代码: Private Sub Form_Load() With udpPeerA .RemoteHost=“197.1.1.2” '要连接到的计算机名 .RemotePort=1010 '要连接到的端口号 .LocalPort=1011 '该Winsock控制将要使用的本地端口号,便于其它端与该Winsock通讯 .Bind 1011 '将该Winsock控制绑定到该本地端口 EndWith End Sub Private Sub txtSend_Change() udpPeerA.SendData txtSend.Text'发送文本 End Sub Private Sub udpPeerA_DataArrival(ByVal bytesTotal As Long) Dim strData As String udpPeerA.GetData strData,vbString txtOutput.Text = strData End Sub UDP应用二: 类似建立UDP Server的方法,在表单上添加一个Winsock控制及两个文本框,然后进行以下属性的设置: 表单(Form):Name=“frmPeerB” Caption=“UDP Application(2)” Winsock控制:Name=“udpPeerB” Protocol=“sckUDPProtoclool” 文本框1(TextBox):Name=“txtSend” 文本框2(TextBox):Name=“txtOutput” MultiLine=True ScrollBars=2 然后输入以下代码: Private Sub Form_Load() With udpPeerB .RemoteHost=“197.1.1.2” '要连接到计算机的IP地址 .RemotePort=1011 '要连接到的端口号 .LocalPort=1010 '该Winsock控制将使用的本地端口号,便于其它方与之通讯 .Bind 1010 '将该Winsock控制绑定到该本地端口 End With End Sub Private Sub txtSend_Change() udpPeerB.SendData txtSend.Text '发送文本 End Sub Private Sub udpPeerB_DataArrival(ByVal bytesTotal As Long) Dim strData As String udpPeerB.GetData strData,vbString txtOutput.Text=strData End Sub 要运行该实例,打开两个Visual Basic的事例,然后分别运行这两个工程文件即可。若要在不同的机器上运行此两例,只需要将两个工程文件中的RemoteHost改变成相应的计算机的IP地址或域名即可。
'* ******************************************************* * '* 程序名称:basComm.bas '* 程序功能:在VB中利用API进行串口通信 '* 作者:lyserver '* 联系方式:http://blog.csdn.net/lyserver '* ******************************************************* * Option Explicit Option Base 0 Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Const GENERIC_READ = &H80000000 Private Const GENERIC_WRITE = &H40000000 Private Const OPEN_EXISTING = 3 Private Const INVALID_HANDLE_VALUE = -1
Private Declare Function GetCommState Lib "kernel32" (ByVal nCid As Long, lpDCB As DCB) As Long Private Declare Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, lpDCB As DCB) As Long Private Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long Private Declare Function SetupComm Lib "kernel32" (ByVal hFile As Long, ByVal dwInQueue As Long, ByVal dwOutQueue As Long) As Long Private Declare Function PurgeComm Lib "kernel32" (ByVal hFile As Long, ByVal dwFlags As Long) As Long Private Const PURGE_TXABORT = &H1 ' Kill the pending/current writes to the comm port. Private Const PURGE_RXABORT = &H2 ' Kill the pending/current reads to the comm port. Private Const PURGE_TXCLEAR = &H4 ' Kill the transmit queue if there. Private Const PURGE_RXCLEAR = &H8 ' Kill the typeahead buffer if there. Private Type DCB DCBlength As Long BaudRate As Long fBitFields As Long 'See Comments in Win32API.Txt wReserved As Integer XonLim As Integer XoffLim As Integer ByteSize As Byte Parity As Byte StopBits As Byte XonChar As Byte XoffChar As Byte ErrorChar As Byte EOFChar As Byte EvtChar As Byte wReserved1 As Integer 'Reserved; Do Not Use End Type Private Type COMMTIMEOUTS ReadIntervalTimeout As Long ReadTotalTimeoutMultiplier As Long ReadTotalTimeoutConstant As Long WriteTotalTimeoutMultiplier As Long WriteTotalTimeoutConstant As Long End Type
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long
'串口操作演示 Sub Main() Dim hComm As Long Dim szTest As String
'打开串口 Function OpenComm(ByVal lComPort As Long) As Long Dim hComm As Long
hComm = CreateFile("COM" & lComPort, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0) If hComm = INVALID_HANDLE_VALUE Then OpenComm = 0 Else OpenComm = hComm End If End Function
'关闭串口 Sub CloseComm(hComm As Long) CloseHandle hComm hComm = 0 End Sub
'读串口 Function ReadComm(ByVal hComm As Long) As Byte() Dim dwBytesRead As Long Dim BytesBuffer() As Byte
ReDim BytesBuffer(4095) ReadFile hComm, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesRead, 0 If dwBytesRead > 0 Then ReDim Preserve BytesBuffer(dwBytesRead) ReadComm = BytesBuffer End If End Function
'写串口 Function WriteComm(ByVal hComm As Long, BytesBuffer() As Byte) As Long Dim dwBytesWrite
If SafeArrayGetDim(BytesBuffer) = 0 Then Exit Function WriteFile hComm, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesWrite, 0 WriteComm = dwBytesWrite End Function
'设置串口通讯参数 Function SetCommParam(ByVal hComm As Long, Optional ByVal lBaudRate As Long = 9600, _ Optional ByVal cByteSize As Byte = 8, Optional ByVal cStopBits As Byte = 0, _ Optional ByVal cParity As Byte = 0, Optional ByVal cEOFChar As Long = 26) As Boolean
Dim dc As DCB If hComm = 0 Then Exit Function
If GetCommState(hComm, dc) Then dc.BaudRate = lBaudRate dc.ByteSize = cByteSize dc.StopBits = cStopBits dc.Parity = cParity dc.EOFChar = cEOFChar
SetCommParam = CBool(SetCommState(hComm, dc)) End If End Function
'设置串口超时 Function SetCommTimeOut(ByVal hComm As Long, Optional ByVal dwReadTimeOut As Long = 2, _ Optional ByVal dwWriteTimeOut As Long = 3) As Boolean
Dim ct As COMMTIMEOUTS If hComm = 0 Then Exit Function
SetCommTimeOut = CBool(SetCommTimeouts(hComm, ct)) End Function
'设置串口读写缓冲区大小 Function SetCommBuffer(ByVal hComm As Long, Optional ByVal dwBytesRead As Long = 1024, _ Optional ByVal dwBytesWrite As Long = 512) As Boolean
If hComm = 0 Then Exit Function SetCommBuffer = CBool(SetupComm(hComm, dwBytesRead, dwBytesWrite)) End Function
'清空串口缓冲区 Sub ClearComm(ByVal hComm As Long, Optional ByVal InBuffer As Boolean = True, Optional ByVal OutBuffer As Boolean = True) If hComm = 0 Then Exit Sub If InBuffer And OutBuffer Then '清空输入输出缓冲区 PurgeComm hComm, PURGE_TXABORT Or PURGE_RXABORT Or PURGE_TXCLEAR Or PURGE_RXCLEAR ElseIf InBuffer Then '清空输入缓冲区 PurgeComm hComm, PURGE_RXABORT Or PURGE_RXCLEAR ElseIf OutBuffer Then '清空输出缓冲区 PurgeComm hComm, PURGE_TXABORT Or PURGE_TXCLEAR End If End Sub
'辅助函数:BSTR字符串转换为CHAR字符串 Function StringToBytes(ByVal szText As String) As Byte() If Len(szText) > 0 Then StringToBytes = StrConv(szText, vbFromUnicode) End If End Function
'辅助函数:CHAR字符串转换为BSTR字符串 Function BytesToString(bytesText() As Byte) As String If SafeArrayGetDim(bytesText) <> 0 Then BytesToString = StrConv(bytesText, vbUnicode) End If End Function
'辅助函数:获得CHAR字符串长度 Function Byteslen(bytesText() As Byte) As Long If SafeArrayGetDim(bytesText) <> 0 Then Byteslen = UBound(bytesText) + 1 End If End Function 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lyserver/archive/2009/05/06/4153335.aspx
由于UDP协议并不需要建立一个明确的连接,因此建立UDP应用要比建立TCP应用简单得多。在TCP应用中,一个Winsock控制必须明确地设置成“监听”,而其它Winsock控制则必须使用Connect方法来初始一个连接。 使用UDP协议,在两个Winsock控制间进行数据的发送,在连接的两端必须完成以下三步:
1.设置RemoteHost属性为其它计算机的名称;
2.设置RemotePort属性为第二个Winsock控制的LocalPort属性的值;
3.申请Bind方法。 通过使用方法Bind,则可将该Winsock控制捆绑到一个本地端口,以便该Winsock控制使用该端口来进行类似TCP的“监听”功能,并防止其它应用使用该端口。 使用该协议传送数据,首先设置客户计算机的LocalPort属性。而作为服务器的计算机仅需要设置RemoteHost属性为客户计算机的IP地址或域名即可,并将其RemotePort属性设置成客户计算机上的LocalPort属性即可,然后就可通过申请SendData方法来开始信息发送,客户计算机则可在其DataArrial事件中使用方法GetData来获取发送的信息。 下例具体演示了一个“谈话”应用,以允许相互间进行实时的交谈。 UDP应用一: 建立一个新标准EXE工程文件,拖放一个Winsock控制到表单上,添加两个文本框到表单上,然后进行以下属性的设置: 表单(Form):Name=“frmPeerA” Caption=“UDP Application(1)”
Winsock控制:Name=“udpPeerA” Protocol=“sckUDPProtocol”
文本框1(TextBox): Name“txtSend”
文本框2(TcxtBox): Name=“txtOutput” MultiLine-True ScrollBars=2 然后打开代码窗口,分别在相应的事件下输入以下代码:
Private Sub Form_Load()
With udpPeerA
.RemoteHost=“197.1.1.2” '要连接到的计算机名
.RemotePort=1010 '要连接到的端口号
.LocalPort=1011 '该Winsock控制将要使用的本地端口号,便于其它端与该Winsock通讯
.Bind 1011 '将该Winsock控制绑定到该本地端口
EndWith
End Sub
Private Sub txtSend_Change()
udpPeerA.SendData txtSend.Text'发送文本
End Sub
Private Sub udpPeerA_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
udpPeerA.GetData strData,vbString
txtOutput.Text = strData
End Sub UDP应用二: 类似建立UDP Server的方法,在表单上添加一个Winsock控制及两个文本框,然后进行以下属性的设置: 表单(Form):Name=“frmPeerB” Caption=“UDP Application(2)”
Winsock控制:Name=“udpPeerB” Protocol=“sckUDPProtoclool”
文本框1(TextBox):Name=“txtSend”
文本框2(TextBox):Name=“txtOutput” MultiLine=True ScrollBars=2 然后输入以下代码:
Private Sub Form_Load()
With udpPeerB
.RemoteHost=“197.1.1.2” '要连接到计算机的IP地址
.RemotePort=1011 '要连接到的端口号
.LocalPort=1010 '该Winsock控制将使用的本地端口号,便于其它方与之通讯
.Bind 1010 '将该Winsock控制绑定到该本地端口
End With
End Sub
Private Sub txtSend_Change()
udpPeerB.SendData txtSend.Text '发送文本
End Sub
Private Sub udpPeerB_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
udpPeerB.GetData strData,vbString
txtOutput.Text=strData
End Sub 要运行该实例,打开两个Visual Basic的事例,然后分别运行这两个工程文件即可。若要在不同的机器上运行此两例,只需要将两个工程文件中的RemoteHost改变成相应的计算机的IP地址或域名即可。
'* ******************************************************* *
'* 程序名称:basComm.bas
'* 程序功能:在VB中利用API进行串口通信
'* 作者:lyserver
'* 联系方式:http://blog.csdn.net/lyserver
'* ******************************************************* *
Option Explicit
Option Base 0
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000
Private Const OPEN_EXISTING = 3
Private Const INVALID_HANDLE_VALUE = -1
Private Declare Function GetCommState Lib "kernel32" (ByVal nCid As Long, lpDCB As DCB) As Long
Private Declare Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, lpDCB As DCB) As Long
Private Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
Private Declare Function SetupComm Lib "kernel32" (ByVal hFile As Long, ByVal dwInQueue As Long, ByVal dwOutQueue As Long) As Long
Private Declare Function PurgeComm Lib "kernel32" (ByVal hFile As Long, ByVal dwFlags As Long) As Long
Private Const PURGE_TXABORT = &H1 ' Kill the pending/current writes to the comm port.
Private Const PURGE_RXABORT = &H2 ' Kill the pending/current reads to the comm port.
Private Const PURGE_TXCLEAR = &H4 ' Kill the transmit queue if there.
Private Const PURGE_RXCLEAR = &H8 ' Kill the typeahead buffer if there.
Private Type DCB
DCBlength As Long
BaudRate As Long
fBitFields As Long 'See Comments in Win32API.Txt
wReserved As Integer
XonLim As Integer
XoffLim As Integer
ByteSize As Byte
Parity As Byte
StopBits As Byte
XonChar As Byte
XoffChar As Byte
ErrorChar As Byte
EOFChar As Byte
EvtChar As Byte
wReserved1 As Integer 'Reserved; Do Not Use
End Type
Private Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long
'串口操作演示
Sub Main()
Dim hComm As Long
Dim szTest As String
'打开串口1
hComm = OpenComm(1)
If hComm <> 0 Then
'设置串口通讯参数
SetCommParam hComm
'设置串口超时
SetCommTimeOut hComm, 2, 3
'向串口写入字符串123
szTest = "123"
WriteComm hComm, StringToBytes(szTest)
'读串口
szTest = BytesToString(ReadComm(hComm))
Debug.Print szTest
'关闭串口
CloseComm hComm
End If
End Sub
'打开串口
Function OpenComm(ByVal lComPort As Long) As Long
Dim hComm As Long
hComm = CreateFile("COM" & lComPort, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
If hComm = INVALID_HANDLE_VALUE Then
OpenComm = 0
Else
OpenComm = hComm
End If
End Function
'关闭串口
Sub CloseComm(hComm As Long)
CloseHandle hComm
hComm = 0
End Sub
'读串口
Function ReadComm(ByVal hComm As Long) As Byte()
Dim dwBytesRead As Long
Dim BytesBuffer() As Byte
ReDim BytesBuffer(4095)
ReadFile hComm, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesRead, 0
If dwBytesRead > 0 Then
ReDim Preserve BytesBuffer(dwBytesRead)
ReadComm = BytesBuffer
End If
End Function
'写串口
Function WriteComm(ByVal hComm As Long, BytesBuffer() As Byte) As Long
Dim dwBytesWrite
If SafeArrayGetDim(BytesBuffer) = 0 Then Exit Function
WriteFile hComm, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesWrite, 0
WriteComm = dwBytesWrite
End Function
'设置串口通讯参数
Function SetCommParam(ByVal hComm As Long, Optional ByVal lBaudRate As Long = 9600, _
Optional ByVal cByteSize As Byte = 8, Optional ByVal cStopBits As Byte = 0, _
Optional ByVal cParity As Byte = 0, Optional ByVal cEOFChar As Long = 26) As Boolean
Dim dc As DCB
If hComm = 0 Then Exit Function
If GetCommState(hComm, dc) Then
dc.BaudRate = lBaudRate
dc.ByteSize = cByteSize
dc.StopBits = cStopBits
dc.Parity = cParity
dc.EOFChar = cEOFChar
SetCommParam = CBool(SetCommState(hComm, dc))
End If
End Function
'设置串口超时
Function SetCommTimeOut(ByVal hComm As Long, Optional ByVal dwReadTimeOut As Long = 2, _
Optional ByVal dwWriteTimeOut As Long = 3) As Boolean
Dim ct As COMMTIMEOUTS
If hComm = 0 Then Exit Function
ct.ReadIntervalTimeout = dwReadTimeOut '读操作时,字符间超时
ct.ReadTotalTimeoutMultiplier = dwReadTimeOut '读操作时,每字节超时
ct.ReadTotalTimeoutConstant = dwReadTimeOut '读操作时,固定超时(总超时=每字节超时*字节数+固定超时)
ct.WriteTotalTimeoutMultiplier = dwWriteTimeOut '写操作时,每字节超时
ct.WriteTotalTimeoutConstant = dwWriteTimeOut '写操作时,固定超时(总超时=每字节超时*字节数+固定超时)
SetCommTimeOut = CBool(SetCommTimeouts(hComm, ct))
End Function
'设置串口读写缓冲区大小
Function SetCommBuffer(ByVal hComm As Long, Optional ByVal dwBytesRead As Long = 1024, _
Optional ByVal dwBytesWrite As Long = 512) As Boolean
If hComm = 0 Then Exit Function
SetCommBuffer = CBool(SetupComm(hComm, dwBytesRead, dwBytesWrite))
End Function
'清空串口缓冲区
Sub ClearComm(ByVal hComm As Long, Optional ByVal InBuffer As Boolean = True, Optional ByVal OutBuffer As Boolean = True)
If hComm = 0 Then Exit Sub
If InBuffer And OutBuffer Then '清空输入输出缓冲区
PurgeComm hComm, PURGE_TXABORT Or PURGE_RXABORT Or PURGE_TXCLEAR Or PURGE_RXCLEAR
ElseIf InBuffer Then '清空输入缓冲区
PurgeComm hComm, PURGE_RXABORT Or PURGE_RXCLEAR
ElseIf OutBuffer Then '清空输出缓冲区
PurgeComm hComm, PURGE_TXABORT Or PURGE_TXCLEAR
End If
End Sub
'辅助函数:BSTR字符串转换为CHAR字符串
Function StringToBytes(ByVal szText As String) As Byte()
If Len(szText) > 0 Then
StringToBytes = StrConv(szText, vbFromUnicode)
End If
End Function
'辅助函数:CHAR字符串转换为BSTR字符串
Function BytesToString(bytesText() As Byte) As String
If SafeArrayGetDim(bytesText) <> 0 Then
BytesToString = StrConv(bytesText, vbUnicode)
End If
End Function
'辅助函数:获得CHAR字符串长度
Function Byteslen(bytesText() As Byte) As Long
If SafeArrayGetDim(bytesText) <> 0 Then
Byteslen = UBound(bytesText) + 1
End If
End Function
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lyserver/archive/2009/05/06/4153335.aspx