【问题标题】:Bad received data C#收到错误的数据 C#
【发布时间】:2020-01-19 15:23:41
【问题描述】:

为什么我收到这个:received string,当我发送这个?sended string

客户端应用的编码:

try
        {

            tcpclient.Connect("127.0.0.1", 80);

            String str = "LOG" + Login.Text + "$" + hasło.Text;
            Stream stm = tcpclient.GetStream();
            ASCIIEncoding asen = new ASCIIEncoding();
            byte[] buffer = asen.GetBytes(str);
            stm.Write(buffer, 0, buffer.Length);

宿主鳕鱼:

  try
        {
            string msg = "";
            Socket socket = Listerner.AcceptSocket();
            ASCIIEncoding asen = new ASCIIEncoding();

            int x = socket.ReceiveBufferSize;
            byte[] buffor = new byte[x];
            int data = socket.Receive(buffor);
            string wiadomość = Encoding.ASCII.GetString(buffor);

【问题讨论】:

  • 因为socket.RecieveBufferSize是缓冲区的大小,而不是数据的大小。 int data 是您收到的字节数,可以与 ReceiveBufferSize 一样高,但在这种情况下,它会更低,并且您应该为字节数组使用大小。如果发送的字节数超过缓冲区,则应再次读取,直到 int data 为 0。
  • 请将发送和接收的字符串粘贴为文本,而不是图片。

标签: c# server


【解决方案1】:

这是因为您在主机上的buffor 变量具有固定大小,因此Encoding.ASCII.GetString 将尝试将完整的字节数组转换回字符串,而不管实际接收到多少字节。

socket.Receive 返回实际接收到的字节数。使用此信息恢复字符串:

int bytesReceived = socket.Receive(buffor);
string wiadomość = Encoding.ASCII.GetString(buffor, 0, bytesReceived);

请参阅 Encoding.ASCII.GetStringSocket.Receive 以供参考。

现在它应该适用于您的小示例。但请注意,您收到的字节数可能会超过缓冲区一次可以接收的字节数。所以你必须这样做:

string messageReceived = "";
int bytesReceived = 0;
do
{
    bytesReceived = socket.Receive(buffor)
    messageReceived += Encoding.ASCII.GetString(buffor, 0, bytesReceived);
} while(bytesReceived >= buffor.Length)
// now messageReceived should contain the whole text

【讨论】:

  • 感谢第一个解决方案有效,但是当手动尝试第二个解决方案时,它会冻结我的服务器。
  • 但是我还有其他问题,为什么如果在列表中我有用户(ala,ala)如果使用相同的,我收到 false? imgur.com/a/WJOfcXo if (Users.Contains(new Userspasword(login, password)))
  • 我的第一个解决方案阻塞,因为 Receive 是阻塞调用。什么是最适合您的,实际上取决于您的主机程序的要求和设计。主机是否应该保持连接打开直到收到下一个数据?客户端会关闭连接吗?但这将远远超出您的问题,因此应该在另一个问题中讨论。我修改了代码,使其不再冻结。此外,对于您评论中的下一个问题,您应该创建一个新问题。这里不是论坛。一问一答。
  • 好的,就像端到端一样。收到回复后关闭。我无法发送新问题。
  • 就像我处理列表一样,我使用了 Exist,因为我不知道为什么 Contains 返回 false,但是这个工作。 if (Users.Exists(x => x.RegisteredUser == login && x.Pasword == password)){return true}
猜你喜欢
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 2014-05-19
相关资源
最近更新 更多