private void _tcpServerFortest_OnRead(Socket soc)
{
// rec = new byte[1];
byte[] rec = _tcpServerFortest.ReceivedBytes;
string str = System.Text.ASCIIEncoding.ASCII.GetString(rec);`
}
我启动TCP服务器的代码是
_tcpServerFortest = new CServerSocket(2005);
_tcpServerFortest .OnConnect += _tcpServerFortest _OnConnect;
_tcpServerFortest .OnDisconnect += _tcpServerFortest _OnDisconnect;
_tcpServerFortest .OnRead += _tcpServerFortest _OnRead;
_tcpServerFortest .Active();
在我的类cServerSocket中,数据接收方法如下
private void OnDataReceived(IAsyncResult asyn)
{
SocketPacket socketData = (SocketPacket)asyn.AsyncState;
try
{
int iRx = socketData.m_currentSocket.EndReceive(asyn);
if (iRx < 1)
{
socketData.m_currentSocket.Close();
if (!socketData.m_currentSocket.Connected)
{
if (OnDisconnect != null)
OnDisconnect(socketData.m_currentSocket);
Clients.Remove(socketData.m_currentSocket);
socketData.m_currentSocket = null;
}
}
else
{
mBytesReceived = socketData.dataBuffer;
char[] chars = new char[iRx + 1];
Decoder d = Encoding.UTF8.GetDecoder();
d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
mTextReceived = new String(chars);
if (OnRead != null)
OnRead(socketData.m_currentSocket);
WaitForData(socketData.m_currentSocket);
}
}
catch (InvalidOperationException ex)
{
if (socketData.m_currentSocket.Connected)
socketData.m_currentSocket.Close();
if (!socketData.m_currentSocket.Connected)
{
if (OnDisconnect != null)
OnDisconnect(socketData.m_currentSocket);
Clients.Remove(socketData.m_currentSocket);
socketData.m_currentSocket = null;
}
else
if (OnError != null)
OnError(ex.Message, null, 0);
}
catch (SocketException se)
{
if (OnError != null)
OnError(se.Message, socketData.m_currentSocket, se.ErrorCode);
if (!socketData.m_currentSocket.Connected)
{
if (OnDisconnect != null)
OnDisconnect(socketData.m_currentSocket);
Clients.Remove(socketData.m_currentSocket);
socketData.m_currentSocket = null;
}
}
}
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
TCP适用于流,而不适用于消息。看来您确实想发送消息,因此UDP可能是一个更好的选择。
在TCP上发送数据时,不能保证这将导致另一侧的单次接收。单个发送可以导致多个接收,并且可以将多个发送批处理为单个接收(如您所知)。您应该连续读取数据,并根据通信协议的要求对其进行解释。就您而言,这很简单,就像“一次读取一个字节”一样-但只有您知道您到底想要什么。
此外,我建议不要使用基于Delphi的通信包装器;编程模型是不同的,似乎创建此库的唯一原因是让熟悉Delphi的人不了解.NET的工作方式。级别太低而无用,而在处理数据时并没有给您太多选择。
不管选择哪种解决方案,您都可以在Stack Overflow上找到数百个类似的问题。例如Handling messages on top of TCP。基本解决方案是:
如果保留TCP,则需要学习如何使用TCP。这意味着处理正常关机(receive返回0个字节),正确读取数据(继续调用receive直到获得完整的消息,将其余的消息保存在缓冲区中以备后用……),错误处理。这意味着了解延迟在TCP上的工作方式(发送并非总是立即发送,除非您明确要求发送)。这意味着要理解,由于某些无关的消息需要重新传输,因此接收到的数据可能会延迟。 TCP并不简单,而且棘手的部分是,它很容易在大多数时间都能正常工作-然后所有假设都被打破了。