【问题标题】:Loosing one Byte over TCP Socket通过 TCP 套接字丢失一个字节
【发布时间】:2015-04-11 05:47:05
【问题描述】:

所以我正在尝试创建一个聊天室。我使用 TCP 套接字发送所有信息。但是当我发送一个字节数组时,接收套接字的缓冲区缺少最后一个字节。它是 0,因为字节数组是 255 大,所以剩下的字节是 0。我通过调试模式检查过,在发送数据包时,数组是正确的。但是在套接字完成接收的断点处,它丢失了最后一个字节。为什么会发生这种情况?我看到另一个线程说你必须停止线程直到套接字完成接收,但我正在使用 AsyncCallBack,据我所知,当套接字完成接收时调用它。

每个数据包中的第一个字节也应该是字符串大小(以考虑额外的空字节)。

数据包类:

public class Packet
{
    public byte[] Buffer;

    public Packet(string message)
    {
        Buffer = new byte[255];

        byte[] messageArray = Encoding.ASCII.GetBytes(message);

        Buffer[0] = (byte)messageArray.GetLength(0);

        for (int i = 0; i < messageArray.GetLength(0); i++)
        {
            Buffer[i+1] = messageArray[i];
        }

    }
    public Packet(byte[] buffer)
    {
        Buffer = buffer;
    }
    public string GetMessage()
    {
        List<byte> messageBuffer = new List<byte>();

        for (int i = 1; i <= Buffer[0]; i++)
        {
            messageBuffer.Add(Buffer[i]);
        }

        return Encoding.ASCII.GetString(messageBuffer.ToArray());
    }

}

Socket类:

class Client
{
    public static List<Client> connectedClients = new List<Client>();
    public Socket Sock;
    public byte[] Buffer = new byte[255];

    public Client(Socket pSock)
    {
        Sock = pSock;
        Sock.BeginReceive(Buffer, 0, 255, SocketFlags.None, new AsyncCallback(RecieveCallBack), null);
    }

    public void Send(byte[] pBuffer)
    {
        Sock.BeginSend(pBuffer, 0, pBuffer.GetLength(0), SocketFlags.None, new AsyncCallback(SendCallBack), null);
    }

    public void SendCallBack(IAsyncResult AR)
    {
        Console.WriteLine("Sent");
        Sock.EndSend(AR);
    }
    public void RecieveCallBack(IAsyncResult AR)
    {
        Sock.EndReceive(AR);

        Packet recPacket = new Packet(Buffer);
        Console.WriteLine(recPacket.GetMessage());

        Sock.BeginReceive(Buffer, 0, 255, SocketFlags.None, new AsyncCallback(RecieveCallBack), null);
    }
}

主服务器程序 `类客户端 { 公共静态列表 connectedClients = new List(); 公共插座袜子; 公共字节[]缓冲区=新字节[255];

    public Client(Socket pSock)
    {
        Sock = pSock;
        Sock.BeginReceive(Buffer, 0, 255, SocketFlags.None, new AsyncCallback(RecieveCallBack), null);
    }

    public void Send(byte[] pBuffer)
    {
        Sock.BeginSend(pBuffer, 0, pBuffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), null);
    }

    public void SendCallBack(IAsyncResult AR)
    {
        Console.WriteLine("Sent");
        Sock.EndSend(AR);
    }
    public void RecieveCallBack(IAsyncResult AR)
    {
        Sock.EndReceive(AR);

        Packet recPacket = new Packet(Buffer);
        Console.WriteLine(recPacket.GetMessage());

        Sock.BeginReceive(Buffer, 0, 255, SocketFlags.None, new AsyncCallback(RecieveCallBack), null);
    }
}`

【问题讨论】:

  • 我假设你知道如果传入的消息大于 254 个字符,它会因为数组不够大而崩溃?
  • 我打算将字符串限制为固定大小。
  • 你使用什么协议? TCP?你能展示你如何实例化Sock 变量吗?

标签: c# sockets tcp server


【解决方案1】:

解决了

错误出现在我没有包含的发送方法中。

sock.BeginSend(sentBuffer[0].Buffer, 0, sentBuffer[0].Buffer[0], SocketFlags.None, new AsyncCallback(SendCallBack), null);

sentBuffer 是一个列表,是一个队列。我把它改成 255 就可以了

【讨论】:

    猜你喜欢
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    相关资源
    最近更新 更多