none
[求助] 使用Socket在Multi-Client for VB2008? RRS feed

  • 問題

  • 我目前使用1Server, 1Client已可對傳資料, 然而, 實際應用必須使用Multi-Client

    底下敘述是從MSDN擷取下來.

    請問:

    1. 第一段, 第二段指的是不是1Server-1Client, 1Server-MultiClient?

    2. 我目前是使用第一段敘述撰寫程式, 若要使用Multi-Clent, 是不是要修改成第二段的敘述? 也就是前面要加Begin.

    3. 若要完成Multi-Client, 可以從第一段修改程式成第二段來完成嗎?

    謝謝回覆!!

    敘述如下:

    ------------------------------------------------------------------------------------------------------------------------

    Socket 類別

    實作 Berkeley 通訊端介面。

    ...

    如果應用程式在執行期間只需要一個執行緒,請使用下列針對同步作業模式設計的方法。

    • 如果您正在使用連接導向通訊協定 (例如 TCP),則伺服器可以使用 Listen 方法來聆聽 (Listen) 連接。Accept 方法會處理任何輸入的連接要求,並傳回可以用來與遠端主機進行資料傳遞的 Socket。使用這個傳回的 Socket 來呼叫 Send Receive 方法。如果您要指定本機 IP 位址和通訊埠編號,請在呼叫 Listen 方法之前呼叫 Bind 方法。如果您要基礎服務提供者為您指派可用的通訊埠,請使用編號為零的通訊埠。如果您要連接至接聽主機,請呼叫 Connect 方法。若要進行資料傳遞,請呼叫 Send Receive 方法。
    • 如果您正在使用無連接通訊協定 (例如 UDP),則根本不需要聆聽連接。呼叫 ReceiveFrom 方法以接受任何輸入的資料包 (Datagram)。使用 SendTo 方法以傳送資料包至遠端主機。

    若要在執行期間使用不同的執行緒來處理通訊,請使用下列針對非同步作業 (Asynchronous Operation) 模式設計的方法。

    2012年10月29日 上午 09:03

解答

所有回覆

  • 那個Begin是非同步呼叫, 多執行緒的範例可以參考:VB.NET MultiThreaded Socket Programming
    2012年10月29日 下午 12:59
  • 謝謝您的回覆!!

    範例是使用TcpListener, TcpClient來實作, 我目前是使用Socket來實作, 也就是上面的第一段敘述, 我想知道如果要從第一段(1Client)轉成Multi-Client, 可以實現嗎? Multi-Client是否一定要非同步才可以? 也就是前面要加Begin.

    2012年10月30日 上午 02:04
  • 那個Begin是非同步呼叫, 多執行緒的範例可以參考:VB.NET MultiThreaded Socket Programming

    原程式Server是使用Console Application, 現在我將它改成Windows Form App, 但是訊息無法顯示在TextBox上, 使用委派也不行, 我要怎麼修改才能顯示在TextBox上.

    謝謝回覆!!

    ----------------------------------------------------------------------------------------------------------

    原程式:

    Imports System.Net.Sockets

    Imports System.Text


    Module Module1

        Sub Main()
            Dim serverSocket As New TcpListener(8888)
            Dim clientSocket As TcpClient
            Dim counter As Integer

            serverSocket.Start()

            msg("Server Started")

            counter = 0
            While (True)
                counter += 1
                clientSocket = serverSocket.AcceptTcpClient()
                msg("Client No:" + Convert.ToString(counter) + " started!")
                Dim client As New handleClinet
                client.startClient(clientSocket, Convert.ToString(counter))
            End While
            clientSocket.Close()
            serverSocket.Stop()
            msg("exit")
            Console.ReadLine()
        End Sub

        Sub msg(ByVal mesg As String)
            mesg.Trim()
            Console.WriteLine(" >> " + mesg)
        End Sub


        Public Class handleClinet
            Dim clientSocket As TcpClient
            Dim clNo As String

            Public Sub startClient(ByVal inClientSocket As TcpClient,ByVal clineNo As String)
                Me.clientSocket = inClientSocket
                Me.clNo = clineNo
                Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf doChat)
                ctThread.Start()
            End Sub

            Private Sub doChat()
                Dim requestCount As Integer
                Dim bytesFrom(10024) As Byte
                Dim dataFromClient As String
                Dim sendBytes As [Byte]()
                Dim serverResponse As String
                Dim rCount As String

                requestCount = 0
                While (True)
                    Try
                        requestCount = requestCount + 1
                        Dim networkStream As NetworkStream = clientSocket.GetStream()

                        NetworkStream.Read(bytesFrom, 0, CInt(clientSocket.ReceiveBufferSize))
                        dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom)
                        dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"))

                        msg("From client-" + clNo + dataFromClient)
                        rCount = Convert.ToString(requestCount)
                        serverResponse = "Server to clinet(" + clNo + ") " + rCount
                        sendBytes = Encoding.ASCII.GetBytes(serverResponse)
                        networkStream.Write(sendBytes, 0, sendBytes.Length)
                        networkStream.Flush()
                        msg(serverResponse)
                    Catch ex As Exception
                        MsgBox(ex.ToString)
                    End Try
                End While
            End Sub
        End Class

    End Module

    修改後程式:

    Imports System.Net.Sockets
    Imports System.Net
    Imports System.Text

    Public Class Form1

        Private Sub btnStartListen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartListen.Click
            Dim intport = CType(txtPort.Text, Integer)
            Dim localAddress As IPAddress = IPAddress.Parse(txtAddress.Text)
            Dim serverSocket As New TcpListener(localAddress, intport)
            Dim clientSocket As TcpClient = Nothing
            Dim counter As Integer

            serverSocket.Start()
            msg("Server Started")
            counter = 0
            While (True)
                counter += 1
                clientSocket = serverSocket.AcceptTcpClient()
                msg("Client No:" + Convert.ToString(counter) + " started!")
                Dim client As New handleClinet
                client.startClient(clientSocket, Convert.ToString(counter))
            End While
            clientSocket.Close()
            serverSocket.Stop()
            msg("exit")
        End Sub

        Public Sub msg(ByVal mesg As String)
            TextBox1.Text += " >> " + mesg & vbCrLf
        End Sub

        Public Class handleClinet
            Dim clientSocket As TcpClient
            Dim clNo As String

            Public Sub startClient(ByVal inClientSocket As TcpClient, ByVal clineNo As String)
                Me.clientSocket = inClientSocket
                Me.clNo = clineNo
                Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf doChat)
                ctThread.Start()
            End Sub

            Private Sub doChat()
                Dim requestCount As Integer
                Dim bytesFrom(10024) As Byte
                Dim dataFromClient As String
                Dim sendBytes As [Byte]()
                Dim serverResponse As String
                Dim rCount As String

                requestCount = 0
                While (True)
                    Try
                        requestCount = requestCount + 1
                        Dim networkStream As NetworkStream = clientSocket.GetStream()
                        networkStream.Read(bytesFrom, 0, CInt(clientSocket.ReceiveBufferSize))
                        dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom)
                        dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"))
                        Form1.msg("From client-" + clNo + dataFromClient)
                        rCount = Convert.ToString(requestCount)
                        serverResponse = "Server to clinet(" + clNo + ") " + rCount
                        sendBytes = Encoding.ASCII.GetBytes(serverResponse)
                        networkStream.Write(sendBytes, 0, sendBytes.Length)
                        networkStream.Flush()
                        Form1.msg(serverResponse)
                    Catch ex As Exception
                        MsgBox(ex.ToString)
                    End Try
                End While
            End Sub
        End Class

        Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd.Click
            End
        End Sub
    End Class

    2012年10月31日 上午 08:32
  • 2012年11月10日 上午 12:23
  • 其實線上手冊裡面就有 Multi-Client 的範例。

    我在 2007 年寫 socket 的程式,就是拿線上手冊範例下去改。

    我的經驗是建議你:

    1. 先跑單緒範例,然後改改看,你會發現單緒範例接受連入後,其他人不能連入。

    2. 跑事件的範例,然後改改看,你會發現處理上反而會讓你無法判定這是哪位仁兄的連線,因為事件是多緒呼叫。

    3. 跑多緒的範例,然後改改看,精簡化後,記得沒事讓該執行緒睡一下。


    T.L. Cheng

    2012年11月17日 上午 03:43
    版主