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