Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving and sending data in C#

I'm still trying to improve a little bit what I wrote before. Now I faced a problem with receiving data. I have a program which I use to send string using tcpClient to a program in which Im listening on a specified port. It works fine so I decided to send data forward one more time

public static void receiveThread()
{
    while (true)
    {
        TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
        tcpListener.Start();

        Console.WriteLine("Waiting for connection...");

        TcpClient tcpClient = tcpListener.AcceptTcpClient();

        Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint);

        while (!(tcpClient.Client.Poll(20, SelectMode.SelectRead)))
        {
            NetworkStream networkStream = tcpClient.GetStream();
            StreamReader streamReader = new StreamReader(networkStream);

            data = streamReader.ReadLine();

            if (data != null)
            {
                Console.WriteLine("Received data: {0}", data);
                send(data); // Here Im using send Method
            }
        }
        Console.WriteLine("Dissconnected...\n");
        tcpListener.Stop();
    }
}

/// <summary>
/// Sending data
/// </summary>
/// <param name="data">Data to send</param>
public static void send(string data)
{
    TcpClient tcpClient = new TcpClient();
    try
    {
        tcpClient.Connect(ipAddress, sendPort);
        Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint);
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
    if (tcpClient.Connected)
    {
        NetworkStream networkStream = tcpClient.GetStream();
        StreamWriter streamWriter = new StreamWriter(networkStream);
        Console.WriteLine("Messege {0} to {1}", data, tcpClient.Client.RemoteEndPoint);
        streamWriter.WriteLine(data);
        streamWriter.Flush();
        tcpClient.Close();
    }
}

Sometimes it works fine, but more often, lets call it a receiver, can't get what Im trying to send. And I really do not konw what is wrong with it. Looks like there can be a problem with send method. Here is an example of receivers output

Waiting for connection...
Connected with 127.0.0.1:52449
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52450
Received data: qweqwe
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52451
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52452
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52453
Received data: zxczx
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52454
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52455
Received data: aasd
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52457
Received data: www
Dissconnected...
like image 745
Allek Avatar asked Dec 03 '09 00:12

Allek


People also ask

How does send () work in C?

The send() function shall initiate transmission of a message from the specified socket to its peer. The send() function shall send a message only when the socket is connected (including when the peer of a connectionless socket has been set via connect()).

How do you send and receive data in a socket?

Create a Socket client. With the endPoint object created, create a client socket to connect to the server. Once the socket is connected, it can send and receive data from the server socket connection. using Socket client = new( ipEndPoint.

How does socket work in C?

Socket programming is a way of connecting two nodes on a network to communicate with each other. One socket(node) listens on a particular port at an IP, while the other socket reaches out to the other to form a connection. The server forms the listener socket while the client reaches out to the server.


2 Answers

Several problems here:

  1. StreamReader has a 4kB buffer and will try to read as much as possible in the first call to ReadLine(). The result is that you might have data in the StreamReader and go into Poll() when there's no more data available because it's already been read.
  2. Poll() takes microseconds. Waiting 0.02ms for incoming data is likely to return false unless the data is there before you call Poll().
  3. You create a new StreamReader on every iteration, which might discard data already read in the previous one.

If you're just going to read lines and want a timeout and a StreamReader, I would do something like:

delegate string ReadLineDelegate ();
...
using (NetworkStream networkStream = tcpClient.GetStream()) {
    StreamReader reader = new StreamReader(networkStream);
    ReadLineDelegate rl = new ReadLineDelegate (reader.ReadLine);
    while (true) {
        IAsyncResult ares = rl.BeginInvoke (null, null);
        if (ares.AsyncWaitHandle.WaitOne (100) == false)
            break; // stop after waiting 100ms
        string str = rl.EndInvoke (ares);
        if (str != null) {
            Console.WriteLine ("Received: {0}", str);
            send (str);
        } 
    }
}
like image 174
Gonzalo Avatar answered Sep 21 '22 05:09

Gonzalo


Ensure that the data actually exists on the stream before chasing ghosts. If there is ALWAYS data we can approach the problem, however looking at it logically it appears as though the stream is either being nulled out or there is just no data on it.

like image 30
Woot4Moo Avatar answered Sep 17 '22 05:09

Woot4Moo