Date: 02/09/11 (C Sharp) Keywords: asp, web, microsoft Hi,
...
public class MathTask {
public string inputData;
public int MaxTryCount;
public int DelayBetweenNotificationsSec;
public bool complete = false;
public MathTask(string _data, int _maxTry, int _delayBetweenNotifications) {
inputData = _data;
MaxTryCount = _maxTry;
DelayBetweenNotificationsSec = _delayBetweenNotifications;
complete = false;
}
}
...
...
private static void Send(Socket handler, MathTask taskData)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(taskData.inputData);
if (taskData.complete || (taskData.MaxTryCount <= 0))
{ // final sending
// Begin sending the data to the remote device.
IAsyncResult res = handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
else
{ // interim (notification) sending
// Begin sending the data to the remote device.
StateObject so = new StateObject();
so.workSocket = handler;
so.sb.Append(taskData.inputData);
IAsyncResult res = handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendInterimCallback), so);
}
}
// after sending notification (task is running)
private static void SendInterimCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
StateObject so = (StateObject)ar.AsyncState;
int bytesSent = so.workSocket.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
// client receives response ONLY AFTER this statement
so.workSocket.Shutdown(SocketShutdown.Both);
so.workSocket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
...
Thanks for response, the problem solved. That was not the server, but the client. Take a look at ReceiveCallback:
private static void ReceiveCallback( IAsyncResult ar ) {
try {
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0) {
// 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(ReceiveCallback), state);
} else {
// All the data has arrived; put it in response.
if (state.sb.Length > 1) {
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
If client reads any bytesRead more than 0, it will store it in buffer and keep waiting for more data to come. Only when 0 bytes read it calls receiveDone.Set(); which finalize the receive process. Now I understand why it was working only after socket became closed.
|