Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Async Socket does not work

1 view
Skip to first unread message

Dan Tran

unread,
Jan 31, 2001, 11:53:24 PM1/31/01
to
Friends, I have a hardtime getting Async socket to work. I have a piece
code that wait for server to send some data. But the WaitOne always return
right away.

Any advice is fully appreciated.

-Dan

byte [] buffer = new Byte[4];


IAsyncResult ar = m_Socket.BeginReceive(buffer, 0, buffer.Length, new
AsyncCallback(OnReceiveBufferComplete), null); //assume I have the callback

if ( ! ar.AsyncWaitHandle.WaitOne(30000, false) ) //30 sec to wait

{

rc = Error.RECV_TIMEOUT;

}

else

{

if ( buffer.Length != m_Socket.EndReceive(ar) )

{

rc = Error.RECV_ERR; <-------------- my code always hits here

}

else

{

size = BitConverter.ToInt32(buffer,0);

}

}

Wendell W. Pinegar

unread,
Feb 1, 2001, 1:22:38 PM2/1/01
to
Dan,

Doesn't waiting on the async handle defeat the purpose of the callback?
Anyway I have this working with NetworkStream.BeginRead() which would be
equalivant to BeginReceive() on the socket. WaitOne() returns true if the
async event was satisified (data was read) and false if the async event
timed out (no data). If you simply wanting to wait until data becomes
available on the socket why not use Socket.Poll instead (which performs a
select on the socket)? Then you can call Socket.Receive directly to read
the data.

"Dan Tran" <dant...@lycos.com> wrote in message
news:OqoTyqAjAHA.1896@tkmsftngp04...

Dan Tran

unread,
Feb 1, 2001, 9:59:21 PM2/1/01
to
Wendell,

You are my hero again.

Here are the reasons why I use BeginConnect

- All my socket operations use BeginXXX model
- This way I can allow user to cancel an operation while waiting for it
ie
IAsyncResult ar = Socket.BeginXXXX (.....)
WaitHandle [] handles = new WaitHandle[2];
handles[0] = ar.AsyncWaitHandle;
handles[1] = myAbortHanlde ; /// use will signal out side
WaitHandle.WaitAny(handles, ...)

So you see why I have to use this technique.

- At his moment, all my BeginConnect, BeginSend, BeginRecieve returns
right
away. I am missing something. MAY BE I HAVE TO SET SOCKETOPTION???


- TCPClient works great with NetworkStream using my technique. But it
only
solve the client side. But I can't create TCPClient on the server side
using a Socket after TCPListen.Accept. So the server side is my
dilema
using TCPClient.

If TCPClient has overload constructor which accetp a Socket. I'd love
it.


- Socket.Poll does not work for me since I cant get out of that call
using
my abortHandle event.


Any thoughts??

-Dan

Wendell W. Pinegar

unread,
Feb 2, 2001, 2:06:21 PM2/2/01
to
Dan,

Well it looks like you have discovered a bug with System.Net.Sockets.Socket.
It appears that all of the async event handles are set to signaled when they
are initialized. I noticed that BeginConnect immediately transfers control
to the callback subroutine instead of calling it upon a successful or failed
connection (when the async event should have been signaled). As you noted
waiting on the async handle returns immediately (again presumably because
the async event handle was initialized to the signaled state).

The same problem happens with BeginReceive. After calling BeginReceive
execution transfers immediatelly to the callback subroutine but there is no
data to be read.

Socket.Poll does work but in your instance it would not be usable.

Sincerely,

Wendell W. Pinegar

"Dan Tran" <dant...@lycos.com> wrote in message

news:#LKqtPMjAHA.2160@tkmsftngp05...

Wendell W. Pinegar

unread,
Feb 2, 2001, 2:32:57 PM2/2/01
to
Dan,

Sorry, my bad. This problem does not occur with BeginReceive(),
BeginAccept(), or BeginSend(). It is isolated to BeginConnect().
BeginReceive() is only immediately signaled if the socket isn't connected
when you call it. Looks like you'll have to use Socket.Poll until this can
be corrected.

"Wendell W. Pinegar" <Wen...@thePinegars.com> wrote in message
news:uh3X8sUjAHA.2160@tkmsftngp03...

Dan Tran

unread,
Feb 2, 2001, 7:23:29 PM2/2/01
to
Wendell,

Look like you and I are having fun with this socket.

I found out, on the server side, I can create NetworkStream using the socket
return form TCPListen.Accept.
This way I can use the stream on both sides the send/receive data.

However, I is very unstable.

My test has the client to send some random data to server and expects the
server the send back the same thing
It always choke on the second iteration.

-Dan


-Dan

"Wendell W. Pinegar" <Wen...@thePinegars.com> wrote in message

news:OzkZz7UjAHA.2176@tkmsftngp02...

Dan Tran

unread,
Feb 3, 2001, 12:39:16 AM2/3/01
to
Base you note,

I set Socket.Connect to be blocking call. After that the BeginSend,
BeginReceive work.

But I still see the same behavior that I have stated in last note.

Hmmm.

-Dan


"Dan Tran" <dant...@lycos.com> wrote in message

news:O8WTKdXjAHA.1036@tkmsftngp03...

Wendell W. Pinegar

unread,
Feb 3, 2001, 1:56:58 PM2/3/01
to
Dan,

Yes, since the async call BeginConnect() is broken you'll either have to use
Connect() or wait on the socket to connect with Poll() or Select() before
you call BeginSend() or BeginReceive().

Again, I'm not seeing the behavior you menthoned with it not working after
the first itteration of sending/receiving data so you'll want to make sure
you are re-enabling callback notification in your OnRead handler by calling
BeginRead()/BeginReceive() again. I've tested this and it is working fine
except for the problem with BeginAccept() as noted in the previous posting.

"Dan Tran" <dant...@lycos.com> wrote in message

news:ucv4nNajAHA.2176@tkmsftngp02...

Wendell W. Pinegar

unread,
Feb 3, 2001, 2:41:40 PM2/3/01
to
Dan,

Each time you receive some data with your async callback you'll want to make
sure you re-enable the callback by calling BeginRead() agaun (or
BeginReceive() if your not using NetworkStream). Also you'll want to put
some logic in this callback so that when the remote end disconnects you bail
out and don't re-enable the async callback (anytime you get bytes received
<= 0). I've just tested your senerio using the NetworkStream for the
connected client on the server and it seems to work fine when
sending/receiving data multiple times (as when the server echos back what
the client sent).

What I have found however is that the OnAccept callback on the server side
only gets called for the first connected client. My OnAccept callback does
not get called upon subsequent client connections unless I first close the
server socket, re-listen and call BeginAccept() again. Very odd. Yet
another bug.

Hey, I did find System.Net.Sockets.Socket.Select() (this is a static class
method so you'll have to call it on the class directly). You can use this
to perform a standard socket select on a collection of socket handles. It
works just like select(). I'm going to ask the .Net development team for an
async version of Select (ie, BeginSelect/EndSelect).

Anyway here is my OnRead callback:

protected void OnRead(IAsyncResult ar)
{
if (ClientSocketStream == null)
return;

// Get the amount of data that was received from the socket.
//
int bytes = ClientSocketStream.EndRead(ar);
if (bytes > 0)
{
string buffer = Encoding.ASCII.GetString(ReadBuffer, 0, bytes);
receivedText.Text = buffer;
} else
{
ClientSocket.Close();
ClientSocketStream = null;
ClientSocket = null;
return;
}

// Send the transmitted data back to the client.
//
ClientSocketStream.Write(ReadBuffer, 0, bytes);

// Wait for more data.
//
ClientSocketStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, new
AsyncCallback(OnRead), null);
}

Wendell W. Pinegar

unread,
Feb 3, 2001, 2:44:31 PM2/3/01
to

Wendell W. Pinegar

unread,
Feb 3, 2001, 2:56:06 PM2/3/01
to
Sorry about the double-post. My ISP is having communications trouble
today...


0 new messages