Asynchronus Socket Programming

I’ve recently done some TCP/IP socket programming. The .Net framework provides a some nice features for making asynchronus program calls. One of the most robust is TCP/IP Sockets.

It can be quite confusing at first to understand the way an asynchronous call and callback mechanism works. I find it easier to understand when I look at the flow of the call first. So here is an outline of the flow.

The basic framework of an asynchronus call is:

  1. Declare the socket
  2. Socket.BeginConnect with ConnectCallback address
  3. ConnectCallback.EndConnect
  4. Socket.BeginSend with SendCallback address
  5. SendCallback.EndSend
  6. Socket.BeginRecieve with RecieveCallback address
  7. RecieveCallback.EndRecieve

And these are the actual function prototypes for an asynchronous TCP/IP socket. This is the outline, I’ll post some real code in another post later.

Dim state As New StateObject 

‘ Create a TCP/IP socket.
Dim client As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
‘ Connect to the remote endpoint.
client.BeginConnect(remoteEP, New AsyncCallback(AddressOf ConnectCallback), state)

Private Sub ConnectCallback(ByVal ar As IAsyncResult)
‘ Retrieve the socket from the state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)

Try
‘ Complete the connection.
state.workSocket.EndConnect(ar)
Catch ex As Exception
End Try
‘now do the send
‘ Begin sending the data to the remote device.
state.workSocket.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), state)End Sub ‘ConnectCallback

Private Sub SendCallback(ByVal ar As IAsyncResult)
‘ Retrieve the socket from the state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)

Try
‘ Complete sending the data to the remote endpoint.
Dim bytesSent As Integer = state.workSocket.EndSend(ar)

Catch ex As Exception
End Try

 ‘now recieve the response
‘ Begin receiving the data from the remote device.
state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
End Sub ‘SendCallback 

Private Sub ReceiveCallback(ByVal ar As IAsyncResult)

‘ 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)
Try 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)
Else ‘ All the data has arrived; put it in response.
 
If state.sb.Length > 1 Then response = state.sb.ToString()End If 

 

End IfCatch ex As ExceptionEnd Try
End Sub ‘ReceiveCallback  

I’ll post the state object class and in another post. I found the easiest way to maintain the connection and shut it down was to have the worksocket in the stateobject.

, , , , , , , , ,

No comments yet.

Leave a Reply