我正在处理一个C#应用程序,该应用程序通过网络实例之间的字符串。
代码当前正在使用异步插座,到目前为止一切都很好(Localhost)。
但是,当我将通过实际界面时,我希望将数据包分开并合并时,我期望缓冲问题。
客户端:
Socket sock;
// Snip init and connect
string msg1 = "HellonWorld";
byte[] data1 = System.Text.Encoding.UTF8.GetBytes(msg1);
sock.Send(data1);
string msg2 = "FoonBarnBaz";
byte[] data2 = System.Text.Encoding.UTF8.GetBytes(msg2);
sock.Send(data2);
我会选择这样的东西,但我无法找到缺失位的优雅解决方案:
服务器:
Socket sock;
MemoryStream ms = new MemoryStream();
Queue<string> strings = new Queue<string>();
// Snip init and receive connection
sock.BeginReceive(buffer, 0, MaxSize, SocketFlags.None, new AsyncCallback(OnReceived), null);
void OnReceived(IAsyncResult result) {
// Snip sanity stuff
int bytesReceived = sock.EndReceive(result);
// Here is where I'd need some help...
ms.Write(buffer, 0, bytesReceived);
ms.Flush();
for (;;) {
StreamReader sr = new StreamReader(ms);
if (sr.HasAStringTerminationCharacter) { // <-- How?
string currentString = sr.ReadUntilTermination(); // <-- How?
strings.Enqueue(currentString);
}
else
break;
}
sock.BeginReceive(buffer, 0, MaxSize, SocketFlags.None, new AsyncCallback(OnReceived), null);
}
作为encoding.getbytes()不预处理或附加字符串终止数据,我使用了binaryReader/binarywriter,该数据在其内容之前编码字符串长度。
这是修改后的客户端:
Socket sock;
// Snip init and connect
sock.Send(ToBinary("HellonWorld"));
sock.Send(ToBinary("FoonBarnBaz"));
byte[] ToBinary(string s) {
var ms = new MemoryStream();
var bw = new BinaryWriter(ms);
bw.Write(s);
bw.Flush();
ms.Flush();
return ms.ToArray();
}
服务器:
Socket sock;
MemoryStream ms = new MemoryStream();
Queue<string> strings = new Queue<string>();
// Snip init and receive connection
sock.BeginReceive(buffer, 0, MaxSize, SocketFlags.None, new AsyncCallback(OnReceived), null);
void OnReceived(IAsyncResult result) {
// Snip sanity stuff
int bytesReceived = sock.EndReceive(result);
ms.Write(buffer, 0, bytesReceived);
ms.Flush();
long endPos = ms.Position;
ms.Seek(0, SeekOrigin.Begin);
long readPos = ms.Position;
var bw = new BinaryReader(ms);
for (;;) {
try {
string currentString = bw.ReadString();
strings.Enqueue(currentString);
readPos = stream.Position;
}
catch (EndOfStreamException) {
long unusedBytes = endPos - readPos;
var remaining = new MemoryStream();
remaining.Write(stream.GetBuffer(), (int) readPos, (int) unusedBytes);
ms = remaining;
break;
}
}
sock.BeginReceive(buffer, 0, MaxSize, SocketFlags.None, new AsyncCallback(OnReceived), null);
}
我相信它将正确处理拆分和合并数据。