向服务器发送多条消息?C#

向服务器发送多条消息?C#,c#,tcp,client-server,tcplistener,C#,Tcp,Client Server,Tcplistener,我有一个又快又脏的问题。目前,我有两个客户端和一个服务器在运行。我可以毫无问题地将消息从客户端传送到服务器。当我想从客户端读取两条消息而不是一条消息时,我的问题就出现了 我收到的错误是:IOException未处理。无法从传输连接读取数据:远程主机强制关闭了现有连接 以下是我在服务器端的代码: 私有静态void HandleClient(对象客户端) { /**创建包含数据库文件对象的列表**/ 列出数据库=新建列表() 这是我的客户代码: ASCIIEncoding encod

我有一个又快又脏的问题。目前,我有两个客户端和一个服务器在运行。我可以毫无问题地将消息从客户端传送到服务器。当我想从客户端读取两条消息而不是一条消息时,我的问题就出现了

我收到的错误是:IOException未处理。无法从传输连接读取数据:远程主机强制关闭了现有连接

以下是我在服务器端的代码:

私有静态void HandleClient(对象客户端) { /**创建包含数据库文件对象的列表**/ 列出数据库=新建列表()

这是我的客户代码:

        ASCIIEncoding encoder = new ASCIIEncoding();
        byte[] buffer = encoder.GetBytes("OptionOneInsert");

        Console.ReadLine(); 
        clientStream.Write(buffer, 0, buffer.Length);
        clientStream.Flush();

        NetworkStream clientStream2 = client.GetStream();
        String text = System.IO.File.ReadAllText("FirstNames.txt");
        clientStream2.Write(buffer, 0, buffer.Length);
        clientStream2.Flush();
        ASCIIEncoding encoder2 = new ASCIIEncoding();

        byte[] buffer2 = encoder2.GetBytes(text);
        Console.WriteLine("buffer is filled with content"); 
        Console.ReadLine();
当客户端发送消息“optionOne”时,服务器会很好地接收到它。只有当我尝试发送名为“text”的字符串时,问题才会出现

任何帮助都将不胜感激-我对套接字不太熟悉,因此我一直在努力理解这一点,现在已经有一段时间了

您在这里遇到了一个大问题-没有什么可以指定一条消息的结尾和另一条消息的开头。很可能服务器会一次性收到两条消息,或者h阿尔夫先给我留言,然后是另一半

避免这种情况的最简单方法是在每条消息前面加上字节数,例如固定的四字节格式。因此,要发送消息,您可以:

  • 将其从字符串编码为字节(理想情况下使用UTF-8而不是ASCII,除非您确定永远不需要任何非ASCII文本)
  • 将字节数组的长度写成四字节值
  • 写出内容
在服务器上:

  • 读取四个字节(如有必要,循环-不能保证您会一起读取这四个字节,尽管您几乎肯定会这样做)
  • 将四个字节转换为整数
  • 分配该大小的字节数组
  • 循环循环,从“当前位置”读取到缓冲区的末尾,直到填满缓冲区
  • 将缓冲区转换为字符串
另一种选择是简单地使用
BinaryReader
BinaryWriter
ReadString
WriteString
使用长度前缀,当然形式略有不同

您可以使用的另一种选择是使用分隔符(例如回车符)但这意味着,如果您需要在要传输的文本中包含分隔符,则需要添加转义。

您遇到了一个大问题-没有任何东西可以指定一条消息的结尾和另一条消息的开头。很有可能服务器会一次收到两条消息,或者半条消息,然后另一半消息

避免这种情况的最简单方法是在每条消息前面加上字节数,例如固定的四字节格式。因此,要发送消息,您可以:

  • 将其从字符串编码为字节(理想情况下使用UTF-8而不是ASCII,除非您确定永远不需要任何非ASCII文本)
  • 将字节数组的长度写成四字节值
  • 写出内容
在服务器上:

  • 读取四个字节(如有必要,循环-不能保证您会一起读取这四个字节,尽管您几乎肯定会这样做)
  • 将四个字节转换为整数
  • 分配该大小的字节数组
  • 循环循环,从“当前位置”读取到缓冲区的末尾,直到填满缓冲区
  • 将缓冲区转换为字符串
另一种选择是简单地使用
BinaryReader
BinaryWriter
ReadString
WriteString
使用长度前缀,当然形式略有不同


您可以使用的另一种选择是使用分隔符(例如回车符)但这意味着,如果您需要在要传输的文本中包含分隔符,则需要添加转义。

您可以再给我们一些服务器端代码吗?另外,您可以发布哪行代码引发了异常吗?没有迹象表明您在
选项未插入后正在向服务器发送任何内容-您没有使用
clientStream2
。当然,我已经在服务器端添加了更多的代码。我还指出了错误发生在服务器端的什么地方。您可以再给我们一些服务器端代码吗?另外,您可以发布哪行代码引发了异常吗?没有迹象表明您在
OptionNeinsert
之后正在向服务器发送任何内容-您“我们没有使用
clientStream2
。当然,我在服务器端添加了更多的代码。我还指出了错误发生在服务器端的什么地方。好的,这很有帮助。我让我的程序停止崩溃。但是正如您所指出的,第二条消息尚未完全收到。非常感谢您的回复!!我想我永远不会尝试和您联系了!”我们再回答一个C#问题。和你的相比,我的会是incomplete@BojanKogoj:一点也不担心。我真诚地感谢任何帮助。C#没关系。有很多不同的方法可以做不同的事情。所以,我希望你仍然愿意帮助别人:哦)我明白了,好的,那很有帮助。我让我的程序停止崩溃。但是正如你所说的,第二条消息未被完全接收。非常感谢您的回复!!我想我再也不会尝试回答C#问题了。与您的相比,我的可能会更好incomplete@BojanKogoj:一点也不担心。我真的很感谢你的帮助。C#没关系。有很多不同的方法可以做不同的事情。所以,我希望你仍然是愿意帮助他人:o)
        ASCIIEncoding encoder = new ASCIIEncoding();
        byte[] buffer = encoder.GetBytes("OptionOneInsert");

        Console.ReadLine(); 
        clientStream.Write(buffer, 0, buffer.Length);
        clientStream.Flush();

        NetworkStream clientStream2 = client.GetStream();
        String text = System.IO.File.ReadAllText("FirstNames.txt");
        clientStream2.Write(buffer, 0, buffer.Length);
        clientStream2.Flush();
        ASCIIEncoding encoder2 = new ASCIIEncoding();

        byte[] buffer2 = encoder2.GetBytes(text);
        Console.WriteLine("buffer is filled with content"); 
        Console.ReadLine();