Socket error when passing a socket with an event

D

darthghandi

I am trying to pass a socket object when an event is signaled. I have
successfully bound to a network interface and listened on a port for
incoming connection. I have also been able to accept that connection
and get the socket. I try to signal an event when this happens and
pass that new socket object when the event happens, but when I try to
pass the socket with this statement:
ConnectionReceived(this, work);
I get this exception in the socket and it's no longer connected:
An unknown, invalid, or unsupported option or level was specified in a
getsockopt or setsockopt call

Any ideas on what I am doing wrong?
Thanks for your time.

Here is the code:

public class SocketEventArgs : EventArgs
{
public Socket theSocket;

public SocketEventArgs(Socket initSock)
{
theSocket = initSock;
}
}

public class Listener
{
public delegate void ConnectionHandler(Object listener,
SocketEventArgs sock);
private Socket m_listener;
private Queue<SocketEventArgs> m_workers;
private bool m_hasSocketsReady;

public ConnectionHandler ConnectionReceived;

public bool HasSocketsReady
{
get
{
return m_hasSocketsReady;
}
set
{
m_hasSocketsReady = value;
}
}

public Listener()
{
m_hasSocketsReady = false;
m_workers = new Queue<SocketEventArgs>();
IPEndPoint theEnd = new IPEndPoint(IPAddress.Any, 9999);
m_listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
m_listener.Bind(theEnd);
m_listener.Listen(20);
}

public Listener(int port)
{
m_hasSocketsReady = false;
IPEndPoint theEnd = new IPEndPoint(IPAddress.Any, port);
m_listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
m_listener.Bind(theEnd);
m_listener.Listen(20);
}

public void AcceptNewConnections()
{
AsyncCallback callme = new AsyncCallback(AddWorkerSocket);
m_listener.BeginAccept(callme, m_listener);
}

private void AddWorkerSocket(IAsyncResult ar)
{
Socket hold = (Socket)ar.AsyncState;
SocketEventArgs work = new
SocketEventArgs(hold.EndAccept(ar));
m_workers.Enqueue(work);
if (work.theSocket.Connected)
{
if (ConnectionReceived != null)
{
ConnectionReceived(this, work);
}
}
AsyncCallback callMe = new AsyncCallback(AddWorkerSocket);
hold.BeginAccept(callMe, hold);
}
}

Here is where I try to subscribe to the event:
private void button6_Click(object sender, EventArgs e)
{
listen = new Listener();
listen.ConnectionReceived += new
Listener.ConnectionHandler(listen_ConnectionReceived);
}

void listen_ConnectionReceived(object listener,
SocketEventArgs sock)
{
if (sock.theSocket.Connected)
{
toolStripStatusLabel1.ForeColor = Color.Blue;
toolStripStatusLabel1.Text = "Bound to " +
sock.theSocket.RemoteEndPoint.ToString();
}
}

private void button7_Click(object sender, EventArgs e)
{
listen.AcceptNewConnections();
}
 
M

Michael Rubinstein

Dear (e-mail address removed) .Any ideas on what I am doing wrong?The short answer is: everything.

In more words, in your case generating events only adds an extra layer of
abstraction, as if asynchronous socket programming is not complex enough. If
you want to signal something triggered within your code, delegates are all
you need. Talking about delegates -

public delegate void ConnectionHandler(Object listener,>
SocketEventArgs sock);

You had to make it public because you initiate it from your GUI (button
click) and the socket you passing is not yet connected. Then you call this
delegate from within a Callback function AddWorkerSocket() instead of
instantiating the delegate right there. You already checked if the socket is
connected, why passing the socket object to a delegate function for the sole
purpose of checking the connection status again and get issues? Besides, if
your code would execute past the if (sock.theSocket.Connected) line, it
would most likely generate a threading exception. I suggest dumping the
events and keeping closer to VS examples.

Michael
 
D

darthghandi

Dear (e-mail address removed) .

Any ideas on what I am doing wrong?

The short answer is: everything.

In more words, in your case generating events only adds an extra layer of
abstraction, as if asynchronous socket programming is not complex enough.If
you want to signal something triggered within your code, delegates are all
you need. Talking about delegates -

public delegate void ConnectionHandler(Object listener,>
SocketEventArgs sock);

You had to make it public because you initiate it from your GUI (button
click) and the socket you passing is not yet connected. Then you call this
delegate from within a Callback function AddWorkerSocket() instead of
instantiating the delegate right there. You already checked if the socketis
connected, why passing the socket object to a delegate function for the sole
purpose of checking the connection status again and get issues? Besides, if
your code would execute past the if (sock.theSocket.Connected) line, it
would most likely generate a threading exception. I suggest dumping the
events and keeping closer to VS examples.

Michael

Thanks, I'll try making it closer to the examples just using a
delegate. By the way, I'm getting rid of the GUI, it was just there
to help me test a few things.
 

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