开发者

Send server multiple messages? C#

开发者 https://www.devze.com 2023-04-07 11:09 出处:网络
I have a quick and dirty question. So as it stands, i have two clients and a server running. I can communicate messages from the clients to the server without any problem. my problem appears when i wa

I have a quick and dirty question. So as it stands, i have two clients and a server running. I can communicate messages from the clients to the server without any problem. my problem appears when i want to read two messages from the client - rather than just one message.

The error which i receive is: IOException was unhandled. Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

Here is my code on the server side:

private static void HandleClientComm(object client) { /** creating a list which contains DatabaseFile objects **/ List theDatabase = new List();

        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();

        byte[] message = new byte[4096];
        int bytesRead;

        do
        {
            bytesRead = 0;

            try
            {
                // Blocks until a client sends a message                    
                bytesRead = clientStream.Read(message, 0, 4096);
            }
            catch (Exception)
            {
                // A socket error has occured
                break;
            }

            if (bytesRead == 0)
            {
                // The client has disconnected from the server
                break;
            }

            // Message has successfully been received
            ASCIIEncoding encoder = new ASCIIEncoding();

            Console.WriteLine("To: " + tcpClient.Client.LocalEndPoint);
            Console.WriteLine("From: " + tcpClient.Client.RemoteEndPoint);
            Console.WriteLine(encoder.GetString(message, 0, bytesRead));


            if (encoder.GetString(message, 0, bytesRead) == "OptionOneInsert")
            {
                byte[] message2 = new byte[4096];
                int bytesRead2 = 0;

                **bytesRead2 = clientStream.Read(message, 0, 4096);** //ERROR occurs here!

                Console.WriteLine("Attempting to go inside insert)");
                Menu.Insert(theDatabase, bytesRead2); 
            }

Here is my client code:

        ASCIIEncoding encoder = new ASCIIEncoding();
        byte[] buffer = encoder.GetBytes("OptionOneInsert");

        Console.ReadLine(); 
        clientStream.Write(buffer, 0, buffer.Length);
        clientStream.Flush();

        NetworkStream clientStream2 = client.GetStream();
        String text = System.IO.File.ReadAllText("FirstNames.txt");
        clientStream2.Write(buffer, 0, buffer.Length);
        clientStream2.Flush();
        ASCIIEncoding encoder2 = new ASCIIEncoding();

        byte[] buffer2 = encoder2.GetBytes(text);
        Console.WriteLine("buffer is filled with content"); 
        Console.ReadLine();

When the client sends the message "optionOne" it is received by the serve开发者_运维问答r just fine. It's only when i attempt to send the string called "text" that the issues appears!

Any help would be greatly appreciated - I'm not all that familiar with Sockets, hence i've been struggling with trying to understand this for sometime now


You've got a big problem here - there's nothing to specify the end of one message and the start of another. It's quite possible that the server will receive two messages in one go, or half a message and then the other half.

The simplest way of avoiding that is to prefix each message with the number of bytes in it, e.g. as a fixed four-byte format. So to send a message you would:

  • Encoding it from a string to bytes (ideally using UTF-8 instead of ASCII unless you're sure you'll never need any non-ASCII text)
  • Write out the length of the byte array as a four-byte value
  • Write out the content

On the server:

  • Read four bytes (looping if necessary - there's no guarantee you'd even read those four bytes together, although you almost certainly will)
  • Convert the four bytes into an integer
  • Allocate a byte array of that size
  • Loop round, reading from "the current position" to the end of the buffer until you've filled the buffer
  • Convert the buffer into a string

Another alternative is simply to use BinaryReader and BinaryWriter - the ReadString and WriteString use length-prefixing, admittedly in a slightly different form.

Another alternative you could use is to have a delimiter (e.g. carriage-return) but that means you'll need to add escaping in if you ever need to include the delimiter in the text to transmit.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号