我正在尝试设置一个tcp连接,它将从外部用户接收xml格式的一些数据,将其解析为数据表,对数据表执行一些繁重的操作,然后转身发送一个xml根据改动回复。
从外观来看,它似乎工作得很好,但随后进行了测试,并发现了一些重大问题。如果同时有多个项目进入,有时会返回错误的数据(如第三个输入发送第四个ins数据回复),并且有可能在极长的xml输入上没有正确接收所有数据。
此代码用于接收传入传输,将它们解析为xml文档,然后将它们发送到相应的部分进行处理。有一些全局声明(比如_TcpClient
),我没有显示初始化,因为我认为他们的数据类型等可能很明显。
private void ReceivePortMessages()
{
int requestCount = 0;
_TcpListener.Start();
Debug.Print(" >> Server Started");
_TcpClient = _TcpListener.AcceptTcpClient();
Debug.Print(" >> Accept connection from client");
while (true)
{
try
{
requestCount = requestCount++;
NetworkStream networkStream = _TcpClient.GetStream();
byte[] bytesFrom = new byte[10025];
networkStream.Read(bytesFrom, 0, (int)_TcpClient.ReceiveBufferSize);
string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("\0"));
XmlDocument xm = new XmlDocument();
xm.LoadXml(string.Format("<root>{0}</root>", dataFromClient));
XmlElement root = xm.DocumentElement;
string rootName = root.FirstChild.Name;
// Sends the data to an appropriate parser operation.
RouteInboundXML(rootName, dataFromClient);
}
catch (ArgumentOutOfRangeException ex)
{
Debug.Print("ReceivePortMessages: Remote client disconnected. " + ex.ToString());
_TcpClient.Close();
_TcpListener.Stop();
ReceivePortMessages();
return;
}
catch (Exception ex)
{
Debug.Print("ReceivePortMessages: " + ex.ToString());
_TcpClient.Close();
_TcpListener.Stop();
ReceivePortMessages();
return;
}
}
}
收到此数据后,xml文档通过一系列操作路由,包括插入数据库,处理插入数据库的数据,然后通过SQL服务代理依赖,选择备份数据并将其转换为xml回复文件。然后,服务代理的依赖关系会调用SendReply
方法向用户返回回复。该代码可以在下面找到:
private void SendReply(string reply)
{
try
{
NetworkStream networkStream = _TcpClient.GetStream();
string serverResponse = reply;
Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
Debug.Print(" >> " + serverResponse);
}
catch (ArgumentOutOfRangeException ex)
{
Debug.Print("SendReply: Remote client disconnected. " + ex.ToString());
_TcpClient.Close();
_TcpListener.Stop();
ReceivePortMessages();
return;
}
}
对我来说这个想法是一个很大的胜利,因为我在网络编程领域(你可能会说)相当缺乏。我已经在这个项目上工作了将近5个月,实际上只剩下这部分要解开了。任何编码建议,阅读材料等帮助我解决这个问题将是令人难以置信的赞赏。提前谢谢。
答案 0 :(得分:0)
你的字节缓冲区是静态的,我会把它从:
切换byte[] bytesFrom = new byte[10025];
为:
byte[] bytesFrom = new byte[tcpClient.ReceiveBufferSize];
另外,我会从:
切换到Unicode编码string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
为:
string dataFromClient = Encoding.UTF8.GetString(bytesFrom);
还要在.Read()之前添加一个读取超时,从10开始略微增加以查看是否有任何更改生效:
networkStream.ReadTimeout = 10;