Avik
Avik

Reputation: 2137

Receiving messages through a socket

In c# when simulating a lan-messenger I am using the loopback address just for testing the current code and am being able to receive the first message I am sending.However after that there aren't any messages reaching the socket.Is there anything to do with clearing a socket buffer?.please help This is the callback function when a connection is made:

private void accepted(IAsyncResult iar)
    {
        Socket server = (Socket)iar.AsyncState;
        Socket client = server.EndAccept(iar);
        if (client.Connected)
        {
            try
            {
                client.BeginReceive(receive, 0, receive.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(rec), client);
            }
            catch (ArgumentException)
            {
                MessageBox.Show("arguments incorrect in begin-receive call", "Error", MessageBoxButtons.OK);
            }
            catch (SocketException)
            {
                MessageBox.Show("error in accessing socket while receiving", "Error", MessageBoxButtons.OK);
            }
            catch (ObjectDisposedException)
            {
                MessageBox.Show("socket closed while receiving", "Error", MessageBoxButtons.OK);
            }
            catch (Exception)
            {
                MessageBox.Show("error while receiving", "Error", MessageBoxButtons.OK);
            }

        }

This is the callback function when the begin-receive method is executed:

void rec(IAsyncResult ar)
    {

        StringBuilder receivedData;
        //String oldvalue;
        Socket remote = (Socket)ar.AsyncState;
        int recv = remote.EndReceive(ar);
        receivedData = new StringBuilder(Encoding.ASCII.GetString(receive, 0, recv));
        //MessageBox.Show(receivedData.ToString(), "received", MessageBoxButtons.OK);
        StringBuilder sb = new StringBuilder(this.textBox1.Text);
        sb.AppendLine(receivedData.ToString());
        if (textBox1.InvokeRequired)
        {
            this.Invoke((MethodInvoker)delegate { this.textBox1.Text = sb.ToString(); });

        }
        remote.Close(5);
        return;
    }

Does it have anything to do with a stringbuilder or string datatype for assigning the data received to a variable.

Upvotes: 0

Views: 3570

Answers (3)

Farzan
Farzan

Reputation: 925

You forgot to call BeginReceive in your rec method:

Here is what your code should be:

void rec(IAsyncResult ar)
{
  StringBuilder receivedData;
  //String oldvalue;
  Socket remote = (Socket)ar.AsyncState;
  int recv = remote.EndReceive(ar);
  receivedData = new StringBuilder(Encoding.ASCII.GetString(receive, 0, recv));
  //MessageBox.Show(receivedData.ToString(), "received", MessageBoxButtons.OK);
  StringBuilder sb = new StringBuilder(this.textBox1.Text);
  sb.AppendLine(receivedData.ToString());
  if (textBox1.InvokeRequired)
  {
    this.Invoke((MethodInvoker)delegate { this.textBox1.Text = sb.ToString(); });

  }
  remote.BeginReceive(receive, 0, receive.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(rec), remote);
  //remote.Close(5);
  return;
}

Of course this code does not close the socket instead will wait for more data. If in your send method you are creating different socket for each message then you need to call BeginAccept instead of BeginReceive.

Hope it helps

Upvotes: 0

Mike Christiansen
Mike Christiansen

Reputation: 1149

Take a look at this. Notice how WaitForData calls itself. This allows the second, and subsequent messages to be received.

You never wait for more data.

    private void OnClientConnect(IAsyncResult asyn)
    {
        m_Client = m_Listener.EndAccept(asyn);
        WaitForData();
    }
    private void WaitForData()
    {
        buffer = new byte[1024];
        m_Client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), null);
    }
    private void OnDataReceived(IAsyncResult asyn)
    {
        int iRx = 0;
        iRx = m_Client.EndReceive(asyn);

        if (iRx > 0)
        {
            PacketReceiver.BytesReceived(buffer);
        }

        if (m_Client.Connected == true)
            WaitForData();
    }

Upvotes: 1

Rodddgers
Rodddgers

Reputation: 33

Here is a 2-part tutorial on C# socket programming, with source code...

http://www.devarticles.com/c/a/C-Sharp/Socket-Programming-in-C-Part-I/1/

http://www.devarticles.com/c/a/C-Sharp/Socket-Programming-in-C-sharp-Part-II/

What is wrong depends entirely on your design. Are you polling? Or, are you waiting for events?

The source is the download.zip file attached to this page: http://www.developerfusion.com/article/3918/socket-programming-in-c-part-1/

Upvotes: 1

Related Questions