请教基于UDP的客户服务器模式的实现?给小弟我参考下,谢谢!
(一)服务器端代码Imports System
Imports
Imports
Imports System.Text
Imports System.Threading
Imports Microsoft.VisualBasic
Public Class StateObject
Public workSocket As Socket = Nothing ' 客户端的socket
Public Const BufferSize As Integer = 1024 ' 接收数据缓冲区大小
Public buffer(BufferSize) As Byte ' 接收数据缓冲区(地址)
Public sb As New StringBuilder '接收数据字符串
End Class
Public Class AsynchronousSocketListener ' 侦听线程
Public Shared allDone As New ManualResetEvent(False)
Public Shared Sub Main()
Dim bytes() As Byte = New [Byte](1023) {}
' 确定本地地址(IP地址和端口号)
Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
Dim localEndPoint As New IPEndPoint(ipAddress, 11000)
' 创建 TCP/IP socket.
Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
' 连接套接字与本地地址,localEndPoint包含哪些内容?值分别是多少?
listener.Bind(localEndPoint)
listener.Listen(100)
While True
allDone.Reset()
' 等待客户请求
Console.WriteLine("Waiting for a connection...")
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
allDone.WaitOne()
End While
End Sub 'Main
Public Shared Sub AcceptCallback(ByVal ar As IAsyncResult)
Dim listener As Socket = CType(ar.AsyncState, Socket)
Dim handler As Socket = listener.EndAccept(ar)
Dim state As New StateObject
state.workSocket = handler
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
End Sub 'AcceptCallback
Public Shared Sub ReadCallback(ByVal ar As IAsyncResult)
Dim content As String = String.Empty
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim handler As Socket = state.workSocket
' Read data from the client socket.
Dim bytesRead As Integer = handler.EndReceive(ar)
If bytesRead > 0 Then
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))
content = state.sb.ToString()
If content.IndexOf("<EOF>") > -1 Then
' 在本地显示读完的数据
Console.WriteLine("Read {0} bytes from socket. " + vbLf + " Data : {1}", content.Length, content)
' 用相同的数据回应客户端.
Send(handler, content)
Else
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
End If
End If
End Sub 'ReadCallback
Private Shared Sub Send(ByVal handler As Socket, ByVal data As String)
' Convert the string data to byte data using ASCII encoding.
Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)
' Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), handler)
End Sub 'Send
Private Shared Sub SendCallback(ByVal ar As IAsyncResult)
' Retrieve the socket from the state object.
Dim handler As Socket = CType(ar.AsyncState, Socket)
' Complete sending the data to the remote device.
Dim bytesSent As Integer = handler.EndSend(ar)
Console.WriteLine("Sent {0} bytes to client.", bytesSent)
handler.Shutdown(SocketShutdown.Both)
handler.Close()
' Signal the main thread to continue.
allDone.Set()
End Sub 'SendCallback
End Class 'AsynchronousSocketListener
(二)客户端代码
Imports System
Imports
Imports
Imports System.Threading
Imports System.Text
Public Class StateObject
Public workSocket As Socket = Nothing
Public Const BufferSize As Integer = 256
Public buffer(BufferSize) As Byte
Public sb As New StringBuilder
End Class 'StateObject
Public Class AsynchronousClient
Private Const port As Integer = 11000 ' 11000是什么?这个值可以改吗?
Private Shared connectDone As New ManualResetEvent(False)
Private Shared sendDone As New ManualResetEvent(False)
Private Shared receiveDone As New ManualResetEvent(False)
Private Shared response As String = String.Empty
Public Shared Sub Main()
Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
Dim remoteEP As New IPEndPoint(ipAddress, port)
' 创建 TCP/IP socket.
Dim client As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
' 向服务器端发送连接请求.
client.BeginConnect(remoteEP, New AsyncCallback(AddressOf ConnectCallback), client)
connectDone.WaitOne()
Send(client, "This is a test<EOF>")
sendDone.WaitOne()
' Receive the response from the remote device.
Receive(client)
receiveDone.WaitOne()
' Write the response to the console.
Console.WriteLine("Response received : {0}", response)
' Release the socket.
client.Shutdown(SocketShutdown.Both)
client.Close()
End Sub 'Main
Private Shared Sub ConnectCallback(ByVal ar As IAsyncResult)
' Retrieve the socket from the state object.
Dim client As Socket = CType(ar.AsyncState, Socket)
' Complete the connection.
client.EndConnect(ar)
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString())
' Signal that the connection has been made.
connectDone.Set()
End Sub 'ConnectCallback
Private Shared Sub Receive(ByVal client As Socket)
' Create the state object.
Dim state As New StateObject
state.workSocket = client
' Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
End Sub 'Receive
Private Shared Sub ReceiveCallback(ByVal ar As IAsyncResult)
' Retrieve the state object and the client socket
' from the asynchronous state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim client As Socket = state.workSocket
' Read data from the remote device.
Dim bytesRead As Integer = client.EndReceive(ar)
If bytesRead > 0 Then
' There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))
' Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
Else
' All the data has arrived; put it in response.
If state.sb.Length > 1 Then
response = state.sb.ToString()
End If
' Signal that all bytes have been received.
receiveDone.Set()
End If
End Sub 'ReceiveCallback
Private Shared Sub Send(ByVal client As Socket, ByVal data As String)
' Convert the string data to byte data using ASCII encoding.
Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)
' Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), client)
End Sub 'Send
Private Shared Sub SendCallback(ByVal ar As IAsyncResult)
' Retrieve the socket from the state object.
Dim client As Socket = CType(ar.AsyncState, Socket)
' Complete sending the data to the remote device.
Dim bytesSent As Integer = client.EndSend(ar)
Console.WriteLine("Sent {0} bytes to server.", bytesSent)
sendDone.Set()
End Sub 'SendCallback
End Class 'AsynchronousClient
现实:编写UDP服务器程序接受UDP客户端程序的命令,并根据命令向UDP客户机做出响应。但UDP客户机向服务器请求getfile命令时,UDP服务器向客户机发送制定文件input中的数据;当UDP客户机向服务器请求gettime命令时,UDP服务器向客户机发送系统当前时间;当UDP客户机向服务器请求其它任何命令时,UDP服务器向客户机发送“这不是正确的命令”。
UDP服务器程序的具体要求如下:
(1)要求程序为命令行程序。例如,可执行文件名为UDPServer.exe,则程序的命令行格式如下。
UDPServer server_port
其中,server_port为服务器的服务端口。
(2)要求将UDP服务器的状态显示在控制台上,具体格式如下。
UDPServer接收命令:……
UDPServer发送命令:……
(3)要求有良好的编程规范和注释。
UDP客户机程序的具体要求如下:
(1)要求程序为命令行程序。例如,可执行文件名为UDPClient.exe,则程序的命令行格式如下。
UDPClient server_addr server_port command
其中,server_addr为服务器的IP地址,server_port为服务器的服务端口,command为客户机发送的命令。
(2)要求将UDP客户机的状态显示在控制台上,具体格式如下。
UDPClient 发送命令:……
UDPClient 接受命令:……
(3)要求有良好的编程规范和注释。
[[it] 本帖最后由 青苔 于 2008-11-12 14:47 编辑 [/it]]