我正在嘗試編寫一個小型客戶端,它將監聽某個端口上的服務器。當我運行我的代碼時,它似乎掛起,那麼它只會給我第一條消息,之後不再接收?我在這裏破壞了我的大腦。任何幫助讚賞。TCP客戶端沒有收到所有消息
Option Strict On
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class Form1
'Form Controls.
Private lblPort As New Label
Private txtPort As New TextBox
Private lblIp As New Label
Private txtIp As New TextBox
Private lblSend As New Label
Private txtSend As New TextBox
Private WithEvents btnConnectSendReceive As New Button
Private lblReceived As New Label
Private lvwReceived As New ListView
Private txtBoxrecieved As New RichTextBox
'Global Objects.
Private gSocket As Socket = Nothing
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Setup form controls.
With Me
.Text = "SplitPackManagerTest"
.Controls.Add(lblPort)
.Controls.Add(txtPort)
.Controls.Add(lblIp)
.Controls.Add(txtIp)
.Controls.Add(lblSend)
.Controls.Add(txtSend)
.Controls.Add(btnConnectSendReceive)
.Controls.Add(lblReceived)
.Controls.Add(lvwReceived)
.Controls.Add(txtBoxrecieved)
.Height = 600
End With
With lblPort
.Text = "Port:"
.Location = New Point(12, 12)
.AutoSize = True
End With
With txtPort
.Text = "3001" 'Same port that server is listening on.
.Location = New Point(100, 12)
End With
With lblIp
.Text = "IP:"
.Location = New Point(12, 42)
.AutoSize = True
End With
With txtIp
.Text = "127.0.0.1" 'Loop-back IP address (localhost).
.Location = New Point(100, 42)
End With
With lblSend
.Text = "Send:"
.Location = New Point(12, 72)
.AutoSize = True
End With
With txtSend
.Text = Chr(2) & "(login (term-id 2))" & Chr(3)
.Location = New Point(100, 72)
End With
With btnConnectSendReceive
.Text = "Connect"
.Location = New Point(12, 122)
.Width = 260
End With
With lblReceived
.Text = "Received Bytes:"
.Location = New Point(12, 182)
.AutoSize = True
End With
With lvwReceived
.Height = 100
.Dock = DockStyle.Bottom
.View = View.Details
.GridLines = True
.FullRowSelect = True
.MultiSelect = False
.Scrollable = True
.Columns.Add("Dec")
.Columns.Add("Hex")
.Columns.Add("Chr")
For Each vCol As ColumnHeader In .Columns
vCol.Width = CInt(Math.Floor(.Width/.Columns.Count)) - CInt(Math.Floor(30/.Columns.Count))
Next
End With
With txtBoxrecieved
.Height = 200
.Dock = DockStyle.Bottom
.ScrollBars = RichTextBoxScrollBars.Both
End With
End Sub
Private Function ConnectSendReceive(ByVal pSendData As Byte(), ByVal pIp As String, ByVal pPort As Integer) As Byte()
'Try creating IP endpoint.
If String.IsNullOrEmpty(pIp) Then Return Nothing
If Not IPAddress.TryParse(pIp, Nothing) Then Return Nothing
Dim vIp As IPAddress = IPAddress.Parse(txtIp.Text)
Dim vEndPoint As New IPEndPoint(vIp, CInt(txtPort.Text))
'Timeout will be 0.5 seconds.
Dim vTimeout As Integer = 500000
'For our little example, we expect all messages to be 1024 bytes or below (arbitrary amount).
Dim vMessageLength As Integer = 1002400000
'Remember, when dimensioning arrays, the integer specified is the upper bounds, not the length.
Dim vServerResponse As Byte() = Nothing
'Initiate socket.
Dim gSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'Connect.
Try
gSocket.Connect(vEndPoint)
Catch ex As Exception
Return Nothing
End Try
If Not gSocket.Connected Then Return Nothing
'Send.
'Socket.SendTimeout = vTimeout
gSocket.Send(pSendData)
txtBoxrecieved.AppendText("Sending.. " & txtSend.Text)
'Receive response.
'Socket.ReceiveTimeout = vTimeout
Dim vBuffer(vMessageLength - 1) As Byte
Dim vNumOfBytesReceived As Integer = 0
Try
vNumOfBytesReceived = gSocket.Receive(vBuffer, 0, vMessageLength, SocketFlags.None)
Catch ex As Exception
Return Nothing
End Try
'Return received bytes.
ReDim vServerResponse(vNumOfBytesReceived - 1)
Array.Copy(vBuffer, vServerResponse, vNumOfBytesReceived)
'Disconnect (since we're using a "Using" statement, the socket will be disconnected here without us explicitly doing it).
Return vServerResponse
End Function
Private Sub btnConnectSendReceive_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnectSendReceive.Click
'Send message and get response from server.
Dim vServerResponse As Byte() = ConnectSendReceive(Encoding.ASCII.GetBytes(txtSend.Text), txtIp.Text, CInt(txtPort.Text))
'Did we receive a response?
If vServerResponse Is Nothing Then MessageBox.Show("Server not reachable/Received no response from server.") : Exit Sub
'Do something with response.
For Each vByte As Byte In vServerResponse
Dim vLvi As New ListViewItem
With vLvi
'Decimal column.
.Text = vByte.ToString
'Hexidecimal column.
.SubItems.Add(vByte.ToString("X2"))
'Character column.
.SubItems.Add(ChrW(vByte))
End With
With lvwReceived
.Items.Add(vLvi)
.EnsureVisible(.Items.Count - 1)
End With
Next
txtBoxrecieved.AppendText(UnicodeBytesToString(vServerResponse))
End Sub
Private Function UnicodeBytesToString(
ByVal bytes() As Byte) As String
Return System.Text.Encoding.ASCII.GetString(bytes)
End Function
End Class
感謝
大衛
gSocket.Receive應該是一個循環。如果消息爲10k,則一次只能接收1k。簡而言之,一次調用該函數並不能保證收到完整的消息。此外,您的評論是錯誤的vMessageLength不是1025字節,它是1克。 vBuffer數組將會很大。 –
感謝那:-)你的意思是一個while循環?對不起,但不是很有經驗...... – Brownd92
是的,你需要循環,直到你收到所有的信息。這意味着您需要接收固定數量的字節或者擁有包含信息大小的數據包頭。 –