我有一个很好的ASYNC tcp流类,我用它连接到perl tcp服务器,然后每隔一段时间就向它发送一个msg。它通常不会很长,从30个字符到200-500个。 95%它工作正常,但我有一个问题,它经常发送消息切断(由一些字符),然后发送其余的消息,这有点打破了事情。有谁能建议如何克服这个问题?我试图改变一些事情,但实际上无法修复它。
public class TcpStream {
private readonly NetworkStream _stream;
public event EventHandler<TcpDataEventArgs> DataReceived;
public event EventHandler<TcpErrorEventArgs> ErrorOccurred;
public TcpStream(NetworkStream stream) {
this._stream = stream;
}
public void BeginRead() {
var state = new SocketState {Stream = _stream};
//var bytes = new byte[1024];
//IAsyncResult ar = _stream.BeginRead(state.Data, 0, state.Data.Length, HandleRead, state);
IAsyncResult ar = _stream.BeginRead(state.Data, 0, state.Data.Length, HandleRead, state);
}
public void Send(byte[] data, ProtocolConnection protocolConnection) {
//try {
_stream.Write(data, 0, data.Length);
//} catch (Exception ex) {
// OnError(new TcpErrorEventArgs(ex, stream, protocolConnection));
// }
}
public void Send(String data, ProtocolConnection protocolConnection) {
byte[] d = Encoding.Default.GetBytes(data);
Send(d, protocolConnection);
}
public void Close() {
_stream.Close();
}
public void Close(int timeout) {
_stream.Close(timeout);
}
public NetworkStream BaseStream {
get { return _stream; }
}
private void HandleRead(IAsyncResult ar) {
var state = (SocketState) ar.AsyncState;
NetworkStream stream = state.Stream;
int r;
// check to see if stream has been closed
if (!stream.CanRead)
return;
// try {
r = stream.EndRead(ar);
// } catch (Exception ex) {
// OnError(new TcpErrorEventArgs(ex, stream, _protocolConnection));
// return;
// }
var rdata = new byte[r];
//var rdata = new byte[1024];
Buffer.BlockCopy(state.Data, 0, rdata, 0, r);
OnData(new TcpDataEventArgs(rdata));
// try {
BeginRead();
// } catch (Exception ex) {
// OnError(new TcpErrorEventArgs(ex, stream, _protocolConnection));
// }
}
private void OnData(TcpDataEventArgs args) {
EventHandler<TcpDataEventArgs> temp = DataReceived;
if (temp != null)
temp(this, args);
}
private void OnError(TcpErrorEventArgs args) {
EventHandler<TcpErrorEventArgs> temp = ErrorOccurred;
if (temp != null)
temp(this, args);
}
private class SocketState {
public readonly byte[] Data = new byte[100];
public NetworkStream Stream;
}
public class TcpDataEventArgs : EventArgs {
public readonly byte[] Data;
public TcpDataEventArgs(byte[] data) {
this.Data = data;
}
}
public class TcpErrorEventArgs : EventArgs {
public readonly Exception Error;
private NetworkStream Stream;
public TcpErrorEventArgs(Exception error, NetworkStream stream) {
this.Error = error;
this.Stream = stream;
}
}
}
答案 0 :(得分:3)
TCP是一种字节流协议。传输的数据包与您的“消息”之间没有直接关系。由您来读取字节并查找消息。
一个非常简单的示例:如果消息是行(以LF或CRLF结尾的字符串),您可以将StreamReader附加到Networkstream并使用ReadLine。不要低估这样做的便利性,UTF-8编码的字符可以分成2个数据包。