请各位高手帮帮忙:
软件环境:
OS: Microsoft Windows Server 2003 Datacenter Edition Service Pack 2
VS2005 Team Suite VB.net
需要源码的请从这里下载.
服务端源码:http://www.xgpcsoft.com/xgsoft/cnblogs/SocketServer.rar
客户端源码:http://www.xgpcsoft.com/xgsoft/cnblogs/SocketClient.rar
这是本人首次用.NET SOCKET 学习!
谢谢各位!
服务端源码:
'思路:
' 1:服务器端有个Listener线程,用来监听。
' 2:服务器端再来个server socket线程,用来和客户端连接。
' 3:当监听到客户连接时,创建server socket线程,独立和客户端连接。
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Public Class ServerSocket
Public SvrIp As IPAddress '监听服务器IP地址
Public SvrPort As Integer '监听服务器端口号
Public Svr As IPEndPoint '服务器地址簇
Public SvrListenSocket As Socket '服务器侦听socket
Public SvrListener As Socket '表示异步操作的状态
Public SvrListenThread As Thread '服务器侦听线程
Public Done As New ManualResetEvent(True) '通知一个或多个正在等待的线程已发生事件
Public receiveDone As New ManualResetEvent(False)
Public alsock As New ArrayList '放置socket的队列
Public TNode As TreeNode
Public mySocket(1000) As Socket
Public ConnSocket As Socket
Public Delegate Sub SetTreeViewCallback()
Public ClientSocket(1000) As Socket
Public conn_client_count As Long
Public tem_str As String
Dim user_ip As String
Dim user_port As String
Dim state As New StateObject
Dim conn_num As Long
Public ClientSocket_conn(1000) As Socket
Public Sub SetNode()
If Tview.InvokeRequired Then
Dim d As New SetTreeViewCallback(AddressOf SetNode)
Me.Invoke(d)
Else
TNode.Nodes.Add(ConnSocket.RemoteEndPoint.ToString)
TNode.ExpandAll()
End If
End Sub
Private Sub btn_Listen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Listen.Click
'判断主机IP格式是否正确
Try
SvrIp = IPAddress.Parse(T_ip.Text)
Catch ex As Exception
MsgBox("您输入的IP地址不正确!")
Exit Sub
End Try
SvrPort = CInt(T_dk.Text)
'侦听1000个客户端 并启动线程
Try
Svr = New IPEndPoint(SvrIp, Int32.Parse(SvrPort))
SvrListenSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
SvrListenSocket.Bind(Svr)
SvrListenSocket.Listen(1000)
SvrListenThread = New Thread(AddressOf ListenThread)
SvrListenThread.Start()
Catch ex As Exception
MsgBox(ex.Message.ToString)
End Try
End Sub
'侦听线程
Public Sub ListenThread()
' Try
While (True)
Done.Reset()
'开始一个异步操作来接受一个传入的连接尝试
SvrListenSocket.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), SvrListenSocket)
Done.WaitOne()
End While
' Catch ex As Exception
'MsgBox(ex.Message.ToString)
'End Try
End Sub
'异步线程的回调函数
Public Sub AcceptCallback(ByVal ar As IAsyncResult)
Done.Set()
SvrListener = ar.AsyncState
ConnSocket = SvrListener.EndAccept(ar)
' Try
Dim state As New StateObject
state.workSocket = ConnSocket
ConnSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
'ConnSocket.Send()
'向队列添加连接到的Socket
'alsock.Add(ConnSocket)
SetNode()
'state.buffer.Initialize()
' Catch ex As Exception
' MsgBox(ex.Message.ToString)
' End Try
End Sub
Public Sub ReadCallback(ByVal ar As IAsyncResult)
Try
Dim ResponseStr As String
Dim state As StateObject
state = ar.AsyncState
'Dim ClientSocket_conn As Socket
Dim ReadBytes As Integer
Dim tokens() As String
Dim tokens_sub() As String
Dim m_info As String
Dim old_len As Long
Dim new_len As Long
Dim sub_len As Long
Done.Set()
If conn_client_count = 0 Then
conn_client_count = 1
Else
conn_client_count = conn_client_count + 1
End If
'data = Encoding.UTF8.GetString(bytes, 0, bytesRec)
ClientSocket_conn(conn_client_count) = state.workSocket
Try
ReadBytes = ClientSocket_conn(conn_client_count).EndReceive(ar)
Catch ex As SocketException ' (SocketException)'出现Socket异常就关闭连接
ClientSocket_conn(conn_client_count).Close() '这个函数用来关闭客户端连接
Exit Sub
End Try
'Dim listener As Socket = CType(ar.AsyncState, Socket)
'Dim handler As Socket = listener.EndAccept(ar)
'ReadBytes = ClientSocket_conn.Receive(state.buffer, StateObject.BufferSize, SocketFlags.None, SocketFlags.None)
If ReadBytes > 0 Then
'state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, ReadBytes))
'Dim bytesRec As Integer = mySocket.Receive(bytes)
'Data = Encoding.UTF8.GetString(bytes, 0, bytesRec)
'将数据累加到 state.sb (StringBuilder) 中
state.sb.Append(System.Text.Encoding.UTF8.GetString(state.buffer, 0, ReadBytes))
'SetNode()
ResponseStr = state.sb.ToString
ResponseStr = System.Text.Encoding.UTF8.GetString(state.buffer, 0, ReadBytes)
'state.buffer.Initialize()'无影响
tem_str = Rb.Text
Rb.Text = ResponseStr
'string second = mystring.Substring(4,2);
'Second=Microsoft.VisualBasic.Right("00avd", 2)
If tem_str <> "" Then
old_len = tem_str.Length
new_len = Rb.Text.Length
sub_len = InStr(1, Rb.Text, tem_str, CompareMethod.Text)
If sub_len <> 0 Then
'ListBox1.Items.Add(Rb.Text.Substring((old_len + 1), (new_len - old_len)))
'ListBox1.Items.Add(Rb.Text)
ListBox1.Items.Add(Microsoft.VisualBasic.Right(Rb.Text, new_len - old_len))
Else '为新的用户
ListBox1.Items.Add(ResponseStr)
End If
Else
ListBox1.Items.Add(ResponseStr)
End If
'判断返回值,提取客户端侦听端口
tokens = ListBox1.Items.Item(ListBox1.Items.Count - 1).ToString.Trim.Split("|")
m_info = ListBox1.Items.Item(ListBox1.Items.Count - 1).ToString
Select Case tokens(0) '分析接收到的数据,可自己定义更多一些
Case "M" '为IP及端口信息
m_info = Microsoft.VisualBasic.Right(m_info, Len(m_info) - 2)
tokens_sub = m_info.Trim.Split("|")
user_ip = tokens_sub(0)
user_port = tokens_sub(1)
'增加已登录用户列表
ListBox2.Items.Add(user_ip & "|" & user_port & "|" & conn_client_count.ToString)
End Select
'向系统投递下一个接收请求
Try
ClientSocket_conn(conn_client_count).BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
Catch ex As SocketException
ClientSocket_conn(conn_client_count).Close() '这个函数用来关闭客户端连接
Exit Sub
End Try
Else
ClientSocket_conn(conn_client_count).Close() '这个函数用来关闭客户端连接
'ClientSocket_conn.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
End If
Catch ex As Exception
MsgBox(ex.Message.ToString)
End Try
End Sub
Private Sub list_socket_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
On Error Resume Next
Dim i As Long
For i = 1 To conn_num
ClientSocket(i).Shutdown(SocketShutdown.Both)
ClientSocket(i).Close()
Next i
For i = 1 To conn_num
If ClientSocket_conn(i).Connected = True Then
ClientSocket_conn(i).Shutdown(SocketShutdown.Both)
ClientSocket_conn(i).Close()
End If
Next i
If SvrListener.Connected = True Then
SvrListener.Shutdown(SocketShutdown.Both)
SvrListener.Close()
End If
If SvrListenSocket.Connected = True Then
SvrListenSocket.Shutdown(SocketShutdown.Both)
SvrListenSocket.Close()
End If
If ConnSocket.Connected = True Then
ConnSocket.Shutdown(SocketShutdown.Both)
ConnSocket.Close()
End If
SvrListenThread.Abort()
End Sub
Private Sub Frm_AuTo_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Control.CheckForIllegalCrossThreadCalls = False
Tview.Nodes.Clear()
TNode = Tview.Nodes.Add("Head", "当前在线终端")
Tview.ExpandAll()
conn_client_count = 0
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim msg As Byte() = Encoding.UTF8.GetBytes("Chat|" + TextBox1.Text)
Dim tem_socket As Long
If Me.CheckBox1.Checked = True Then '向指定的用户发送信息
'提取指定用户编号 ListBox2.Items.Add(user_ip & "|" & user_port & "|" & conn_client_count.ToString)
Dim tokens() As String
If ListBox2.SelectedItem = "" Then Exit Sub
tokens = ListBox2.SelectedItem.ToString.Trim.Split("|")
If tokens(2).Length = 0 Then Exit Sub
tem_socket = CLng(tokens(2).ToString)
ClientSocket_conn(tem_socket).BeginSend(msg, 0, msg.Length, SocketFlags.None, New AsyncCallback(AddressOf SendCallBack), ClientSocket_conn(tem_socket))
Else '向当前最后通信连接的用户发送信息
ClientSocket_conn(conn_client_count).BeginSend(msg, 0, msg.Length, SocketFlags.None, New AsyncCallback(AddressOf SendCallBack), ClientSocket_conn(conn_client_count))
End If
End Sub
Private Sub SendCallBack(ByVal ar As IAsyncResult)
Dim info As Socket
'UserInfo info = (UserInfo)ar.AsyncState;
info = ar.AsyncState
' info.workSocket.EndSend(ar)
info.EndSend(ar)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
End Sub
End Class
' State object for reading client data asynchronously
Public Class StateObject
' Client socket.
Public workSocket As Socket = Nothing
' Size of receive buffer.
Public Const BufferSize As Integer = 1024
' Receive buffer.
Public buffer(BufferSize) As Byte
' Received data string.
Public sb As New StringBuilder
End Class 'StateObject
客户端:
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Public Class SocketClient
'客户端Socket
Dim cliSocket As Socket
'连接状态
Dim IsConnected As Boolean = False
'接收信息线程
Dim myThread As Thread
Dim listener As Socket
'服务端的Socket
'与客户端会话的Socket
Dim mySocket As Socket
'服务端的运行状态
Dim IsRun As Boolean = False
'监听接收数据线程
Dim ServerThread As Thread
Dim ServerSocket As Socket
Dim my_ip As String
Dim my_port As Long
Dim IPAdress As System.Net.IPAddress
Dim HostName As String
Sub ReciveMsg()
Dim bytes() As Byte = New Byte(1024) {}
Dim data As String = String.Empty
Dim tokens() As String
While True
Dim bytesRec As Integer = cliSocket.Receive(bytes)
data = Encoding.UTF8.GetString(bytes, 0, bytesRec)
tokens = data.Trim.Split("|")
Select Case tokens(0) '分析接收到的数据,可自己定义更多一些
Case "Exit"
IsConnected = False
BeginInvoke(New EventHandler(AddressOf AddInfo), tokens(1)) 'Invoke保证线程安全
cliSocket.Shutdown(SocketShutdown.Both)
cliSocket.Close()
Exit Sub
Case "Chat"
BeginInvoke(New EventHandler(AddressOf AddInfo), tokens(1)) 'Invoke保证线程安全
Case Else
BeginInvoke(New EventHandler(AddressOf AddInfo), data) 'Invoke保证线程安全
End Select
End While
End Sub
'发送信息
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim msg As Byte() = Encoding.UTF8.GetBytes(HostName + ":" + TextBox1.Text)
Dim bytesSent As Integer = cliSocket.Send(msg)
ListBox1.Items.Add("本地信息: " + TextBox1.Text)
TextBox1.Text = ""
End Sub
'非UI线程调用窗体控件,保证线程安全。与聊天实现无关。
Sub AddInfo(ByVal sender As System.Object, ByVal e As System.EventArgs)
ListBox1.Items.Add("远程信息: " + sender.ToString)
End Sub
'关闭窗口时发关退出信息并清理资源
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
On Error Resume Next
If IsConnected Then
'Dim msg As Byte() = Encoding.UTF8.GetBytes("Exit|客户端退出: " + Me.Handle.ToString)
'Dim bytesSent As Integer = cliSocket.Send(msg)
myThread.Abort()
If ServerSocket.Connected = True Then
ServerSocket.Shutdown(SocketShutdown.Both)
ServerSocket.Close()
End If
listener.Close()
ServerThread.Abort()
If cliSocket.Connected = True Then
cliSocket.Shutdown(SocketShutdown.Both)
cliSocket.Close()
End If
End If
End Sub
Private Sub btn_Listen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Listen.Click
Dim remoteEP As New IPEndPoint(Net.IPAddress.Parse("192.168.1.188"), 1111)
HostName = System.Net.Dns.GetHostName '获得本机的机器名
IPAdress = System.Net.Dns.GetHostByName(HostName).AddressList.GetValue(0) '获得本机的IP
cliSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Try
cliSocket.Connect(remoteEP)
ListBox1.Items.Add("连接服务端成功!")
IsConnected = True
myThread = New Thread(AddressOf ReciveMsg)
myThread.Start()
'发送客户端信息
Dim msg As Byte() = Encoding.UTF8.GetBytes("M|" & HostName & "|" & IPAdress.ToString)
Dim bytesSent As Integer = cliSocket.Send(msg)
Catch ex As Exception
ListBox1.Items.Add(ex.Message)
End Try
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.Close()
End Sub
Private Sub Button3_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
On Error Resume Next
If IsConnected Then
'Dim msg As Byte() = Encoding.UTF8.GetBytes("Exit|客户端退出: " + Me.Handle.ToString)
'Dim bytesSent As Integer = cliSocket.Send(msg)
myThread.Abort()
If ServerSocket.Connected = True Then
ServerSocket.Shutdown(SocketShutdown.Both)
ServerSocket.Close()
End If
listener.Close()
ServerThread.Abort()
If cliSocket.Connected = True Then
cliSocket.Shutdown(SocketShutdown.Both)
cliSocket.Close()
End If
End If
End Sub
End Class
浙公网安备 33010602011771号