Async socket communication

  • Thread starter =?ISO-8859-1?Q?Linus_R=F6rstad?=
  • Start date
?

=?ISO-8859-1?Q?Linus_R=F6rstad?=

Hi!

I'm having a problem using asynchronous socket communication over UDP to
connect to a NTP server. The problem I'm having is if I use synchronous
communication to the server all is fine but if I switch over to
asynchronous communication nothing is received.

private void Start(string host)
{
try
{
IPHostEntry hostadd = Dns.Resolve(host);
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);

TimeSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);

TimeSocket.Blocking = false;

//Connect the time server
timeoutTimer = new Timer(new TimerCallback(OnTimedOut), null,
timeout*1000, System.Threading.Timeout.Infinite);

TimeSocket.BeginConnect(EPhost, new AsyncCallback(OnConnect),
TimeSocket);

while(connectionStatus != ConnectionStatus.Connected)
{
if(connectionStatus == ConnectionStatus.Disconnected)
throw new SocketException();
}

// Initialize data structure
Initialize();

// Initialize the transmit timestamp
transmitTimestamp = DateTime.Now;

SocketStateObject so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new
AsyncCallback(OnSent), so2);

while(connectionStatus != ConnectionStatus.DataSent)
{
if(connectionStatus == ConnectionStatus.TimedOut)
throw new SocketException();
}

so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginReceive(data, 0, data.Length, 0, new
AsyncCallback(OnReceived), so2);

while(connectionStatus != ConnectionStatus.DataReceived)
{
if(connectionStatus == ConnectionStatus.TimedOut)
{
throw new SocketException();
}
}
}
catch(SocketException e)
{
throw new SocketException(e.Message);
}

}

public void OnConnect(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
Socket sock = (Socket) iar.AsyncState;
sock.EndConnect(iar);
Console.WriteLine("Connected=" + sock.Connected.ToString());
if(sock.Connected == true)
{
connectionStatus = ConnectionStatus.Connected;
}
else
connectionStatus = ConnectionStatus.Disconnected;
}

public void OnSent(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

try
{
if (s == null || !s.Connected)
return;
int send = s.EndSend(iar);
connectionStatus = ConnectionStatus.DataSent;
Console.WriteLine(iar.ToString());
}
catch {}
}

public void OnReceived(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

if (s == null || !s.Connected)
return;
int read = s.EndReceive(iar);
if (read > 0)
{
string msg = Encoding.ASCII.GetString(data, 0, read);
connectionStatus = ConnectionStatus.DataReceived;
}
else
{
connectionStatus = ConnectionStatus.TimedOut;
}
}

public void OnTimedOut(Object o)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
connectionStatus = ConnectionStatus.TimedOut;
}

I'm I doing something wrong?
Thanks
Linus
 
P

Paul G. Tobey [eMVP]

This all seems unnecessarily complicated. Why not just use the synchronous
socket code from a worker thread and forget about connections, etc. and
simply send and receive the datagrams that you need to get the time? When
you say "nothing" is received, what do you mean by that, specifically? Have
you captured the network data using a sniffer to confirm whether the server
is sending a response?

Paul T.

Linus Rörstad said:
Hi!

I'm having a problem using asynchronous socket communication over UDP to
connect to a NTP server. The problem I'm having is if I use synchronous
communication to the server all is fine but if I switch over to
asynchronous communication nothing is received.

private void Start(string host)
{
try
{
IPHostEntry hostadd = Dns.Resolve(host);
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);

TimeSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);

TimeSocket.Blocking = false;

//Connect the time server
timeoutTimer = new Timer(new TimerCallback(OnTimedOut), null,
timeout*1000, System.Threading.Timeout.Infinite);

TimeSocket.BeginConnect(EPhost, new AsyncCallback(OnConnect),
TimeSocket);

while(connectionStatus != ConnectionStatus.Connected)
{
if(connectionStatus == ConnectionStatus.Disconnected)
throw new SocketException();
}

// Initialize data structure
Initialize();

// Initialize the transmit timestamp
transmitTimestamp = DateTime.Now;

SocketStateObject so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new
AsyncCallback(OnSent), so2);

while(connectionStatus != ConnectionStatus.DataSent)
{
if(connectionStatus == ConnectionStatus.TimedOut)
throw new SocketException();
}

so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginReceive(data, 0, data.Length, 0, new
AsyncCallback(OnReceived), so2);

while(connectionStatus != ConnectionStatus.DataReceived)
{
if(connectionStatus == ConnectionStatus.TimedOut)
{
throw new SocketException();
}
}
}
catch(SocketException e)
{
throw new SocketException(e.Message);
}

}

public void OnConnect(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
Socket sock = (Socket) iar.AsyncState;
sock.EndConnect(iar);
Console.WriteLine("Connected=" + sock.Connected.ToString());
if(sock.Connected == true)
{
connectionStatus = ConnectionStatus.Connected;
}
else
connectionStatus = ConnectionStatus.Disconnected;
}

public void OnSent(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

try
{
if (s == null || !s.Connected)
return;
int send = s.EndSend(iar);
connectionStatus = ConnectionStatus.DataSent;
Console.WriteLine(iar.ToString());
}
catch {}
}

public void OnReceived(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

if (s == null || !s.Connected)
return;
int read = s.EndReceive(iar);
if (read > 0)
{
string msg = Encoding.ASCII.GetString(data, 0, read);
connectionStatus = ConnectionStatus.DataReceived;
}
else
{
connectionStatus = ConnectionStatus.TimedOut;
}
}

public void OnTimedOut(Object o)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
connectionStatus = ConnectionStatus.TimedOut;
}

I'm I doing something wrong?
Thanks
Linus
 
?

=?ISO-8859-1?Q?Linus_R=F6rstad?=

Thanks for your reply.

If I use the synchronous way the thread will be blocked in the Receive
method. And from what I have tried there will be no timeout which I need
to have.

I have used a sniffer and no response is received which I find where
weird. How can it differ?

Sincerly
Linus
This all seems unnecessarily complicated. Why not just use the synchronous
socket code from a worker thread and forget about connections, etc. and
simply send and receive the datagrams that you need to get the time? When
you say "nothing" is received, what do you mean by that, specifically? Have
you captured the network data using a sniffer to confirm whether the server
is sending a response?

Paul T.

Hi!

I'm having a problem using asynchronous socket communication over UDP to
connect to a NTP server. The problem I'm having is if I use synchronous
communication to the server all is fine but if I switch over to
asynchronous communication nothing is received.

private void Start(string host)
{
try
{
IPHostEntry hostadd = Dns.Resolve(host);
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);

TimeSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);

TimeSocket.Blocking = false;

//Connect the time server
timeoutTimer = new Timer(new TimerCallback(OnTimedOut), null,
timeout*1000, System.Threading.Timeout.Infinite);

TimeSocket.BeginConnect(EPhost, new AsyncCallback(OnConnect),
TimeSocket);

while(connectionStatus != ConnectionStatus.Connected)
{
if(connectionStatus == ConnectionStatus.Disconnected)
throw new SocketException();
}

// Initialize data structure
Initialize();

// Initialize the transmit timestamp
transmitTimestamp = DateTime.Now;

SocketStateObject so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new
AsyncCallback(OnSent), so2);

while(connectionStatus != ConnectionStatus.DataSent)
{
if(connectionStatus == ConnectionStatus.TimedOut)
throw new SocketException();
}

so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginReceive(data, 0, data.Length, 0, new
AsyncCallback(OnReceived), so2);

while(connectionStatus != ConnectionStatus.DataReceived)
{
if(connectionStatus == ConnectionStatus.TimedOut)
{
throw new SocketException();
}
}
}
catch(SocketException e)
{
throw new SocketException(e.Message);
}

}

public void OnConnect(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
Socket sock = (Socket) iar.AsyncState;
sock.EndConnect(iar);
Console.WriteLine("Connected=" + sock.Connected.ToString());
if(sock.Connected == true)
{
connectionStatus = ConnectionStatus.Connected;
}
else
connectionStatus = ConnectionStatus.Disconnected;
}

public void OnSent(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

try
{
if (s == null || !s.Connected)
return;
int send = s.EndSend(iar);
connectionStatus = ConnectionStatus.DataSent;
Console.WriteLine(iar.ToString());
}
catch {}
}

public void OnReceived(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

if (s == null || !s.Connected)
return;
int read = s.EndReceive(iar);
if (read > 0)
{
string msg = Encoding.ASCII.GetString(data, 0, read);
connectionStatus = ConnectionStatus.DataReceived;
}
else
{
connectionStatus = ConnectionStatus.TimedOut;
}
}

public void OnTimedOut(Object o)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
connectionStatus = ConnectionStatus.TimedOut;
}

I'm I doing something wrong?
Thanks
Linus
 
P

Paul G. Tobey [eMVP]

Yes, that's a common way to have threading work. In fact, it's the *right*
way to do it. Threads which are blocked, those which are waiting for data,
for example, should *not* be consuming processor cycles, which they will be
in your asynchronous case. There are situations where absolute speed is
essential and polling methods are often faster in those cases, but I don't
see this as one of those cases where it's necessary.

Make sure that you are actually sending a *UDP* packet to the server, that
the packet is being sent to the correct *port* on the server, and that the
*content* of the packet is right. If all of those are correct, then we have
something unusual. Most likely you broke your code when changing from
synchronous to asynch.

Paul T.

Linus Rörstad said:
Thanks for your reply.

If I use the synchronous way the thread will be blocked in the Receive
method. And from what I have tried there will be no timeout which I need
to have.

I have used a sniffer and no response is received which I find where
weird. How can it differ?

Sincerly
Linus
This all seems unnecessarily complicated. Why not just use the
synchronous socket code from a worker thread and forget about
connections, etc. and simply send and receive the datagrams that you need
to get the time? When you say "nothing" is received, what do you mean by
that, specifically? Have you captured the network data using a sniffer
to confirm whether the server is sending a response?

Paul T.

Hi!

I'm having a problem using asynchronous socket communication over UDP to
connect to a NTP server. The problem I'm having is if I use synchronous
communication to the server all is fine but if I switch over to
asynchronous communication nothing is received.

private void Start(string host)
{
try
{
IPHostEntry hostadd = Dns.Resolve(host);
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);

TimeSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);

TimeSocket.Blocking = false;

//Connect the time server
timeoutTimer = new Timer(new TimerCallback(OnTimedOut), null,
timeout*1000, System.Threading.Timeout.Infinite);

TimeSocket.BeginConnect(EPhost, new AsyncCallback(OnConnect),
TimeSocket);

while(connectionStatus != ConnectionStatus.Connected)
{
if(connectionStatus == ConnectionStatus.Disconnected)
throw new SocketException();
}

// Initialize data structure
Initialize();

// Initialize the transmit timestamp
transmitTimestamp = DateTime.Now;

SocketStateObject so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new
AsyncCallback(OnSent), so2);

while(connectionStatus != ConnectionStatus.DataSent)
{
if(connectionStatus == ConnectionStatus.TimedOut)
throw new SocketException();
}

so2 = new SocketStateObject(TimeSocket);
timeoutTimer.Change(timeout*1000, System.Threading.Timeout.Infinite);
TimeSocket.BeginReceive(data, 0, data.Length, 0, new
AsyncCallback(OnReceived), so2);

while(connectionStatus != ConnectionStatus.DataReceived)
{
if(connectionStatus == ConnectionStatus.TimedOut)
{
throw new SocketException();
}
}
}
catch(SocketException e)
{
throw new SocketException(e.Message);
}

}

public void OnConnect(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
Socket sock = (Socket) iar.AsyncState;
sock.EndConnect(iar);
Console.WriteLine("Connected=" + sock.Connected.ToString());
if(sock.Connected == true)
{
connectionStatus = ConnectionStatus.Connected;
}
else
connectionStatus = ConnectionStatus.Disconnected;
}

public void OnSent(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

try
{
if (s == null || !s.Connected)
return;
int send = s.EndSend(iar);
connectionStatus = ConnectionStatus.DataSent;
Console.WriteLine(iar.ToString());
}
catch {}
}

public void OnReceived(IAsyncResult iar)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
SocketStateObject so = (SocketStateObject)iar.AsyncState;
Socket s = so.WorkSocket;

if (s == null || !s.Connected)
return;
int read = s.EndReceive(iar);
if (read > 0)
{
string msg = Encoding.ASCII.GetString(data, 0, read);
connectionStatus = ConnectionStatus.DataReceived;
}
else
{
connectionStatus = ConnectionStatus.TimedOut;
}
}

public void OnTimedOut(Object o)
{
timeoutTimer.Change(System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
connectionStatus = ConnectionStatus.TimedOut;
}

I'm I doing something wrong?
Thanks
Linus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top