Client server socket C#

前端 未结 2 1180
情深已故
情深已故 2020-12-12 07:19

I am working on socket C#. I\'ve implemented a client server application using socket, but the problem is that the client doesn\'t receive all data sent by the server.

2条回答
  •  醉话见心
    2020-12-12 07:34

    First of all. If you're implementing some kind of streaming feature ( tcp/udp/file ) you should consider using some kind of protocol.

    What is a protocol? It's just a scheme to use when streaming data. Example:

    [4Bytes - length][lengthBytes - message][1Byte - termination indicator]

    Knowing the protocol you can read all of the incoming bytes simply as such :

    byte[] buffer = new byte[4];
    stream.ReadBytes(buffer, 0, 4); // cast that to int and read the rest
    
    int packetLen = BitConverter.ToInt32(buffer, 0);
    buffer = new byte[packetLen];
    stream.ReadBytes(buffer, 0, buffer.Length); // all bytes that was sent
    

    Remember that you have to subtract thease 4 bytes in the length before sending the message.

    EDIT:

    Simple example on how to send and receive data using shared protocol.

    // sender.cs
    string _stringToSend = "some fancy string";
    byte[] encodedString = Encoding.UTF8.GetBytes(_stringToSend);
    List buffer = new List();
    buffer.AddRange(BitConverter.GetBytes(encodedString.Length));
    buffer.AddRange(encodedString);
    netStream.WriteBytes(buffer.ToArray(), 0, buffer.Count);
    // netStream sent message in protocol [@LEN - 4Bytes][@MSG - @LENBytes]
    // simply speaking something like: 5ABCDE
    
    // receiver.cs
    byte[] buffer = new byte[sizeof(int)];
    netStream.ReadBytes(buffer, 0, buffer.Length);
    // receiver got the length of the message eg. 5
    int dataLen = BitConverter.ToInt32(buffer, 0);
    buffer = new byte[dataLen];
    // now we can read an actual message because we know it's length
    netStream.ReadBytes(buffer, 0, buffer.Length);
    string receivedString = Encoding.UTF8.GetString(buffer);
    // received string is equal to "some fancy string"
    

    Making it simpler

    This technique forces you to use desired protocol which in this example will be :

    First 4 bytes sizeof(int) are indicating the length of the incoming packet Every byte further is your packet until the end.

    So right now you should make ProtocolHelper object:

    public static class ProtocolHelper
    {
        public byte[] PackIntoProtocol(string message)
        {
            List result = new List();
            byte[] messageBuffer = Encoding.UTF8.GetBytes(message);
            result.AddRange(BitConverter.GetBytes(messageBuffer.Length), 0); // this is the first part of the protocol ( length of the message )
            result.AddRange(messageBuffer); // this is actual message
            return result.ToArray();
        }
    
        public string UnpackProtocol(byte[] buffer)
        {
            return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
        }
    }
    

    Now ( depending on method you've chosen to read from network ) you have to send and receive your message.

    // sender.cs
    string meMessage = "network message 1";
    byte[] buffer = ProtocolHelper.PackIntoProtocol(meMessage);
    socket.Send(buffer, 0, buffer.Length, 0);
    
    // receiver.cs
    string message = string.Empty;
    byte[] buffer = new byte[sizeof(int)]; // or simply new byte[4];
    int received = socket.Receive(buffer);
    if(received == sizeof(int))
    {
        int packetLen = BitConverter.ToInt32(buffer);// size of our message
        buffer = new byte[packetLen]; 
        received = socket.Receive(buffer);
        if( packetLen == received ) // we have full buffer
        {
            message = PacketHelper.UnpackProtocol(buffer);
        }
    }
    Console.WriteLine(message); // output: "network message 1"
    

提交回复
热议问题