我有一个快速而肮脏的问题。因此,我有两个客户端和一个服务器正在运行。我可以毫无问题地将消息从客户端传送到服务器。当我想从客户端读取两条消息时,我的问题就出现了 - 而不仅仅是一条消息。
我收到的错误是:IOException未处理。无法从传输连接读取数据:远程主机强制关闭现有连接。
这是我在服务器端的代码:
private static void HandleClientComm(object client) { / **创建一个包含DatabaseFile对象的列表** / 列出theDatabase = 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”时,服务器就会收到它。只有当我尝试发送名为“text”的字符串时才会出现问题!
任何帮助都会非常感激 - 我对套接字并不熟悉,因此我一直在努力尝试理解这个问题
答案 0 :(得分:3)
这里有一个大问题 - 没有什么可以指定一条消息的结束和另一条消息的开头。很可能服务器将一次接收两条消息,或者一半消息,然后是另一半消息。
避免这种情况的最简单方法是在每条消息前面加上字节数,例如:作为固定的四字节格式。所以要发送消息你会:
在服务器上:
另一个替代方案是使用BinaryReader
和BinaryWriter
- ReadString
和WriteString
使用长度前缀,不可否认,形式略有不同。
可能使用的另一个替代方法是使用分隔符(例如回车符),但这意味着如果您需要在文本中包含分隔符以进行传输,则需要添加转义符