user2663994
user2663994

Reputation:

c# length of data througth StreamWriter

I have written a code for client server using tcp/sockets in c# which is working perfectly fine. My problem is that why I am able to send only limited size data from client to server at a single instance.

Following is my server code

public class AsynchIOServer
{
// server port number
const int port = 8001;
// server ip address
const string ip = "127.0.0.1";

const int maxBuffer = 10000;

static IPAddress ipAddress = IPAddress.Parse(ip);
static TcpListener tcpListener = new TcpListener(ipAddress, port);


static void Listeners()
{
    try
    {
        Socket socketForClient = tcpListener.AcceptSocket();

        if (socketForClient.Connected)
        {
            Console.WriteLine("Client : " + socketForClient.RemoteEndPoint + " is now connected to server.");
            NetworkStream networkStream = new NetworkStream(socketForClient);
            System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
            System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream);

            while (true)
            {
                string theString = streamReader.ReadLine();
                if (theString != "exit")
                {
                    // original message from client
                    Console.WriteLine("------------------------------------------------------------------------------");
                    Console.WriteLine("Message recieved from client(" + socketForClient.RemoteEndPoint + ") : " + theString);

                    // ASCII code for the message from client 
                    Console.Write("ASCII Code for message is : ");
                    foreach (char c in theString)
                    {
                        Console.Write(System.Convert.ToInt32(c) + " ");
                    }

                    // Hex value of message from client
                    string hex = "";
                    foreach (char c in theString)
                    {
                        int tmp = c;
                        hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
                    }
                    Console.WriteLine();
                    Console.WriteLine("Hex Code for the message from client : " + hex);

                    //sending acknowledgement to client
                    Console.WriteLine();
                    socketForClient.Send(new ASCIIEncoding().GetBytes(/*"The string was recieved from Client(" + socketForClient.RemoteEndPoint + ") : " + */theString));

                } // end of if loop

                // if exit from client
                else
                {
                    Console.WriteLine();
                    Console.WriteLine("Client " + socketForClient.RemoteEndPoint + " has exited");
                    break;
                }

            } // end of  while loop

            streamReader.Close();
            networkStream.Close();
            streamWriter.Close();

        } // end of if loop

        socketForClient.Close();
        Console.WriteLine();
        // Console.WriteLine("Press any key to exit from server program");
        Console.ReadKey();

    } // end of try loop

    catch (Exception e) 
    {
        Console.WriteLine("The process failed: {0}", e.ToString());
        Console.WriteLine("Message not received from client");
    }

} // end of Listener loop

// Number of clients that can connect to the server
public static void Main()
{
    tcpListener.Start();

    Console.WriteLine("********** This is the Server program **********");
    Console.Write("Number of Clients that can connect to Server : ");

    int numberOfClientsYouNeedToConnect = int.Parse(Console.ReadLine());
    for (int i = 0; i < numberOfClientsYouNeedToConnect; i++)
    {
        Thread newThread = new Thread(new ThreadStart(Listeners));
        newThread.Start();
    }
    Console.WriteLine();

} // end of Min Loop

} // end of public class AsynchIOServer

while my client code is

public class Client
{
// For acknowledgement from server
const int maxBuffer = 1000;

static public void Main(string[] Args)
{
    // ip address of server to which client should be connected
    string ip;
    // port number at which server is listening for client connection
    int port;

    Console.Write("Enter the ip address: ");
    ip = Console.In.ReadLine();

    Console.Write("Enter the port number: ");
    port = int.Parse(Console.In.ReadLine());

    TcpClient socketForServer;

    try
    {
        // connect to server at ipaddress ip and port number port
        socketForServer = new TcpClient(ip, port);
    }
    catch
    {
        Console.WriteLine("Failed to connect to server at {0}:{1}", ip , port);
        Console.ReadLine();
        return;
    }

    // Initializing StreamReader and StreamWriter for sending or reading message from server
    NetworkStream networkStream = socketForServer.GetStream();
    System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream);
    System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);

    try
    {
        Console.WriteLine();
        Console.WriteLine("---Begin sending message(type 'exit' to disconnect from server)---");
        Console.WriteLine();

        Console.Write("Type message : ");
        string str = Console.ReadLine();

        while (str != "exit")
        {
            streamWriter.WriteLine(str);
            streamWriter.Flush();

            // For receiving acknowledgement from server
            byte[] receiveBuffer = new byte[maxBuffer];
            int k = networkStream.Read(receiveBuffer, 0, maxBuffer);
            for (int i = 0; i < k; i++)
                Console.Write(/*Convert.ToChar(*/receiveBuffer[i]);
            Console.WriteLine();
            Console.WriteLine("------------------------------------------------------");

            Console.Write("Type message : ");
            str = Console.ReadLine();
        }

        // For client to close connection with server
        if (str == "exit")
        {
            streamWriter.WriteLine(str);
            streamWriter.Flush();
        }
    } // end of try loop

    catch
    {
        Console.WriteLine("Exception reading from Server");
    }

    // exit the client
    networkStream.Close();
    Console.WriteLine("Press any key to exit from client program");
    Console.ReadKey();

} // End of Main loop

} // End of public class Client

Now when I run my program I enter following binary to be sent from client as first message

Type message : 11111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111

Problem is that it doesn't allow me enter more binary data. I can send more binary data if I want to send by pressing enter and then sending as 2nd message. But I want to send it as single message. So is their any limit to send more data at single instance over tcp/sockets?

Upvotes: 0

Views: 1721

Answers (2)

Icermann
Icermann

Reputation: 181

That has to do with the ReadLine method limiting input to 256 characters, see Remarks section for a workaround:

http://msdn.microsoft.com/en-us/library/system.console.readline.aspx

edit: typo

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182769

Your assessment of the problem is wrong. There are no messages -- TCP has no such thing as application-level messages because TCP is not a message protocol, it's a byte stream protocol that provides a stream of bytes, not messages. There is no such thing as "send it as single message" nor is there such as thing as "sending as 2nd message". It's just sending bytes and receiving bytes. If you want to receive more bytes, call receive again.

If you want to implement messages, you can do so. But you have to do it. You have to define, specify, and implement a protocol that sends and receives messages on top of TCP. You have to specify how messages will be delimited, send delimited messages, and write receive code to detect the delimiters and assemble the received byte stream into messages. It won't happen by itself.

The simplest solution is to read and write lines delimited by newline characters, assuming your "messages" can't contain newlines.

Upvotes: 1

Related Questions