我有一个很好的异步TCP流类,我用它连接到PerlTCP服务器,然后每隔一段时间就会向它发送消息。它通常不会很长,从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;
}
}
}