请各位高手帮帮忙:

软件环境:
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


 

posted on 2007-10-28 00:37  xgpcsoft  阅读(2785)  评论(7)    收藏  举报