Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

.net - Client server socket C#

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.

Here is the client application code. What should I do so that it would receive all data sent by the server?

strRecieved = "";
Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9001);
soc.Connect(endPoint);
byte[] msgBuffer = Encoding.Default.GetBytes(path);
soc.Send(msgBuffer, 0, msgBuffer.Length, 0);
byte[] buffer = new byte[2000];
int rec = soc.Receive(buffer);

strRecieved = String.Format(Encoding.Default.GetString(buffer));
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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<byte> buffer = new List<byte>();
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<byte> result = new List<byte>();
        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"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...