Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 客户端服务器套接字C_C#_.net_Sockets - Fatal编程技术网

C# 客户端服务器套接字C

C# 客户端服务器套接字C,c#,.net,sockets,C#,.net,Sockets,我正在开发socket C。我已经使用socket实现了一个客户机-服务器应用程序,但问题是客户机没有接收到服务器发送的所有数据 这是客户端应用程序代码。我应该怎么做才能让它接收服务器发送的所有数据 strRecieved = ""; Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint endPoint = new IPEndPoint(IPAd

我正在开发socket C。我已经使用socket实现了一个客户机-服务器应用程序,但问题是客户机没有接收到服务器发送的所有数据

这是客户端应用程序代码。我应该怎么做才能让它接收服务器发送的所有数据

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));

首先。如果你正在执行某种流媒体特性TCP/UDP/文件,你应该考虑使用某种协议。p> 什么是协议?这只是一种在流式传输数据时使用的方案。例如:

[4字节-长度][长度字节-消息][1字节-终止指示符]

了解协议后,您可以简单地读取所有传入字节:

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
请记住,在发送消息之前,必须先减去长度中的ase 4字节

编辑:

关于如何使用共享协议发送和接收数据的简单示例

现在,根据您选择的从网络读取信息的方法,您必须发送和接收信息

// 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"

当您使用新字节[2000]时,您将接收到的消息的大小限制为2KB。 我想你可以:

调整缓冲区的大小以满足消息的大小需求;和/或 将消息拆分为多个套接字消息。 假设4-8K是一个字节,并且假设RAM大小不是一个问题,我将从新字节[8000]开始

此外,您还可以发送分块的套接字消息。也许这对这个案子来说是个好主意。例如,如果要发送的消息或对象为msg:

private static async Task SendAnswer(Message msg, WebSocket socket)
{
    var answer = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msg).ToCharArray());

    var bufferSize = 8000;
    var endOfMessage = false;
    for (var offset = 0; offset < answer.Length; offset += bufferSize)
    {
        if (offset + bufferSize >= answer.Length)
        {
            bufferSize = answer.Length - offset;
            endOfMessage = true;
        }
        await socket.SendAsync(new ArraySegment<byte>(answer, offset, bufferSize),
            WebSocketMessageType.Text, endOfMessage, CancellationToken.None);
    }
}
在接收时,您还可以将接收分块,以便控制缓冲区,从而减少内存消耗。在处理完整个消息之后,您应该等待来自客户端的另一条消息来执行更多操作


你已经创建了一个IP套接字发送给你自己。。示例中的路径似乎未定义。这条路有多大?更准确地说,msgbuffer有多大?你的接收缓冲区有没有可能只得到你告诉它的2000字节?消息更大?确切地说,要接收的消息更大,我没有收到整个消息,我应该怎么做才能将可能接收的消息设置为最大值?谢谢为什么要将缓冲区设置为2000?是的,我是c新手,我设置为2000,应该如何将其设置为maximu?并非所有数据都将在一个块中接收。代码必须继续读取,直到数据结束。您还必须包括确定终点的方法。因此,请使用以下3种方法中的一种或多种方法1 Ascii:使用“\n”或“\0”等不属于消息的字符终止数据。2 Ascii或二进制:将字节计数添加到消息的开头3 Ascii或二进制:固定长度消息。我使用tcp ip协议,只需检查我输入的源代码,什么是变量netStream,我使用SokSet.rceivebuffer如何更新我的代码谢谢lot@m.rogaski在类协议助手中,变量结果是什么?它的类型是什么?
// 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"
private static async Task SendAnswer(Message msg, WebSocket socket)
{
    var answer = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msg).ToCharArray());

    var bufferSize = 8000;
    var endOfMessage = false;
    for (var offset = 0; offset < answer.Length; offset += bufferSize)
    {
        if (offset + bufferSize >= answer.Length)
        {
            bufferSize = answer.Length - offset;
            endOfMessage = true;
        }
        await socket.SendAsync(new ArraySegment<byte>(answer, offset, bufferSize),
            WebSocketMessageType.Text, endOfMessage, CancellationToken.None);
    }
}
private async Task ReceiveMessage(WebSocket webSocket)
{
    var buffer = new byte[8000];
    var result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
    while (!result.CloseStatus.HasValue)
    {
        string msg = Encoding.UTF8.GetString(new ArraySegment<byte>(buffer, 0, result.Count).ToArray());
        while (!result.EndOfMessage)
        {
            result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
            msg += Encoding.UTF8.GetString(new ArraySegment<byte>(buffer, 0, result.Count).ToArray());
        }

        //At this point, `msg` has the whole message you sent, you can do whatever you want with it.
        // [...]
        //After you handle the message, wait for another message from the client
        result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
    }
    await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}