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:
- Declare the socket
- Socket.BeginConnect with ConnectCallback address
- ConnectCallback.EndConnect
- Socket.BeginSend with SendCallback address
- SendCallback.EndSend
- Socket.BeginRecieve with RecieveCallback address
- 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.