向服务器发送多条消息?c#
本文关键字:消息 服务器 | 更新日期: 2023-09-27 18:09:18
我有一个快速而肮脏的问题。所以现在,我有两个客户端和一个服务器在运行。我可以毫无问题地从客户端向服务器发送消息。当我想从客户机读取两条消息而不是一条消息时,问题就出现了。
我收到的错误是:IOException未处理。无法从传输连接读取数据:远程主机强制关闭了现有连接。
下面是我在服务器端的代码: HandleClientComm(对象客户端){/**创建一个包含DatabaseFile对象的列表**/List = new List() TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
do
{
bytesRead = 0;
try
{
// Blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch (Exception)
{
// A socket error has occured
break;
}
if (bytesRead == 0)
{
// The client has disconnected from the server
break;
}
// Message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("To: " + tcpClient.Client.LocalEndPoint);
Console.WriteLine("From: " + tcpClient.Client.RemoteEndPoint);
Console.WriteLine(encoder.GetString(message, 0, bytesRead));
if (encoder.GetString(message, 0, bytesRead) == "OptionOneInsert")
{
byte[] message2 = new byte[4096];
int bytesRead2 = 0;
**bytesRead2 = clientStream.Read(message, 0, 4096);** //ERROR occurs here!
Console.WriteLine("Attempting to go inside insert)");
Menu.Insert(theDatabase, bytesRead2);
}
下面是我的客户端代码:
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"时,它被服务器正常接收。只有当我试图发送名为"文本"的字符串时,问题才会出现!
任何帮助都将非常感激-我不太熟悉Sockets,因此我一直在努力理解这一段时间了
这里有一个大问题——没有什么可以指定一条消息的结束和另一条消息的开始。服务器很有可能一次接收到两条消息,或者接收到一半消息,然后再接收到另一半消息。
避免这种情况的最简单方法是在每个消息前加上字节数,例如固定的四字节格式。因此,要发送消息,您需要:
- 将其从字符串编码为字节(理想情况下使用UTF-8而不是ASCII,除非您确定从不需要任何非ASCII文本)
- 将字节数组的长度写成一个四字节的值
- 写出内容
服务器端:
- 读取四个字节(必要时循环-不能保证你甚至会同时读取这四个字节,尽管你几乎肯定会)
- 将四个字节转换为整数
- 分配该大小的字节数组
- 循环,从"当前位置"读取到缓冲区的末尾,直到填满缓冲区
- 将缓冲区转换为字符串
另一种选择是简单地使用BinaryReader
和BinaryWriter
- ReadString
和WriteString
使用长度前缀,诚然,在一个稍微不同的形式。
可以使用的另一种选择是使用分隔符(例如回车),但这意味着如果您需要在要传输的文本中包含分隔符,则需要添加转义。