We're building a brand new version of the site, and we'd love to hear your ideas
Members
Technology Zones
IBM Learning Center
Articles
Hosted By
Info
|
[3997] Socket Programming in C# - Part 2
Last post 06-05-2007 5:07 AM by afas. 40 replies.
-
Advertisement
|
|
-
-
-
-
-
-
gcadmes


- Joined on 04-27-2006
- United States

- Points 5
|
Re: [3997] Socket Programming in C# - Part 2
The following source code example has some un-safe thread issues.
Within the public method OnDataReceived(IAsyncResult asyn)
txtDataRx.Text = txtDataRx.Text + szData;
|
|
-
-
-
AG


- Joined on 02-21-2007

- Points 10
|
Re: Problems with multiple clients connecting
Hi,
I am new to this forum but I am trying to do exactly what you may have achieved!
I am trying to connect multiple clients to Server!
Any Help is appriciated
AG
|
|
-
-
-
hager


- Joined on 03-05-2007

- Points 10
|
Re: [3997] Socket Programming in C# - Part 2
Hi
how can i acknowledege an sending message in asynchronous socket program????
thank you
|
|
-
-
afas


- Joined on 06-05-2007
- Brazil

- Points 5
|
Re: [3997] Socket Programming in C# - Part 2
I was having the same problem until some minutes ago. The code below worked for me. See the bold section. Take a look at the help for Socket.Poll. This will return True only if there is still data to be received in the connected socket. If there's not, it sends the OK message.
I'll also post the whole code for the Client and Server classes. It may be useful for someone. I spend several hours researching and testing to come up with this...
I know we are in a C# area, but the code is very easy to translate.
Private Sub ReceiveCallback(ByVal ar As IAsyncResult) Try '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) 'Check if there is no more data to be received. If not an OK message is sent to the client. If Not client.Poll(1000000, SelectMode.SelectRead) Then Send(client, "OK" & vbCrLf) End If Else 'All the data has arrived; 'Signal that all bytes have been received. receiveDone.Set() InvokeDelegate(state.sb.ToString) End If Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
###See the complete solution below: _____________________________________________________________________________
Public Delegate Sub StringReceivedHandlerDelegate(ByVal sRemoteAddress As String)
Public Class Server
Private _PortNumber As Integer Private DataReceived As StringReceivedHandlerDelegate Private listener As Socket
Sub New(ByVal PortNumber As Integer) _PortNumber = PortNumber End Sub
Public Sub StartServer() Listen() End Sub
Public Sub StopServer() If Not listener Is Nothing Then listener.Close() End If End Sub
Public Class StateObject 'Client socket. Public workSocket As Socket = Nothing 'Size of receive buffer. Public Const BufferSize As Integer = 8192 'Receive buffer. Public buffer() As Byte = New Byte(BufferSize - 1) {} 'Received data string. Public sb As New StringBuilder End Class
'ManualResetEvent instances signal completion. Private Shared connectDone As New ManualResetEvent(False) Private Shared sendDone As New ManualResetEvent(False) Private Shared receiveDone As New ManualResetEvent(False)
Private Sub Listen() Try Dim remoteEP As New IPEndPoint(IPAddress.Any, _PortNumber) listener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) listener.Bind(remoteEP) listener.Listen(10) listener.BeginAccept(New AsyncCallback(AddressOf ConnectCallback), listener) Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
Private Sub ConnectCallback(ByVal ar As IAsyncResult) Try 'Retrieve the socket from the state object. Dim client As Socket = CType(ar.AsyncState, Socket) 'Complete the connection. client = client.EndAccept(ar) Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString()) 'Start Receiving Receive(client) 'Signal that the connection has been made. connectDone.Set() listener.BeginAccept(New AsyncCallback(AddressOf ConnectCallback), listener) Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
Private Sub Receive(ByVal client As Socket) Try '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) Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
Private Sub ReceiveCallback(ByVal ar As IAsyncResult) Try '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) 'Check if there is no more data to be received an OK message is sent to the client If Not client.Poll(1000000, SelectMode.SelectRead) Then Send(client, "OK" & vbCrLf) End If Else 'All the data has arrived; 'Signal that all bytes have been received. receiveDone.Set() InvokeDelegate(state.sb.ToString) End If Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
Private Sub Send(ByVal client As Socket, ByVal data As String) Try '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) Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
Private Sub SendCallback(ByVal ar As IAsyncResult) Try '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) 'Signal that all bytes have been sent. sendDone.Set() Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
Public Sub SetStringInputHandler(ByVal pMethod As StringReceivedHandlerDelegate) Try Monitor.Enter(Me) If DataReceived Is Nothing Then DataReceived = pMethod End If Monitor.Exit(Me) Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
Private Sub InvokeDelegate(ByVal sData As String) Try DataReceived.Invoke(sData) Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub
End Class
____________________________________________________________________________
Public Class Client
Private _RemoteHost As String Private _RemotePort As Integer Private _NetworkStream As NetworkStream Dim _TCPClient As TcpClient
Sub New(ByVal RemoteHost As String, ByVal RemotePort As Integer) _RemoteHost = RemoteHost _RemotePort = RemotePort End Sub
Public Function SendStringMessage(ByVal Message As String) As String Try _TCPClient = New TcpClient(_RemoteHost, _RemotePort) _NetworkStream = _TCPClient.GetStream() '_NetworkStream.WriteTimeout = 10000 '_NetworkStream.ReadTimeout = 10000 Dim strResponse As String ' Send a string (newline terminated) to the server. Dim writer As New System.IO.StreamWriter(_NetworkStream) Dim reader As New System.IO.StreamReader(_NetworkStream) writer.Write(Message) writer.Flush() ' Read server response (up to a newline). Try strResponse = reader.ReadLine Catch ex As Exception strResponse = Nothing End Try 'Close writer.Close() reader.Close() _NetworkStream.Close() Return strResponse Catch ex As Exception Return Nothing Finally If Not _TCPClient Is Nothing Then _TCPClient.Close() _TCPClient = Nothing End If End Try End Function
End Class
Holpe it helped.
Regards,
Afas.
|
|
|
Search
Code Samples
New Members
|