gpt4 book ai didi

C# 网络 : Server hangs after receiving more than 65535 bytes

转载 作者:行者123 更新时间:2023-11-30 16:32:20 25 4
gpt4 key购买 nike

更新:由于 Stackoverflow 上的管理员出现问题,我在 MSDN 论坛上发布了同一问题的精简版本。下面的文本使用了 MyNetworking.dll,但这不是问题所在。这是一个非常精简的客户端-服务器,问题是完全一样的。随时尝试一下 =) http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/d3d33eb9-7dce-4313-929e-a8a63d0f1e03/更新

所以,我有一个奇怪的错误。

通常,我们有一个 DLL 来处理我们的网络。让我们调用它 MyNetworking.dll。我们在服务器和客户端的任何地方都使用它,并且已经这样做了 5 年。直到现在,我还没有遇到任何问题。

我有一个“XMLPoller”,它从 MySQL 数据库中读取 XML,将其序列化为 byte[] 数组并通过网络发送。这些特定的 XML 消息是 627 字节的序列化形式。

XMLPoller 连接到“远程服务器”(恰好是本地主机)上的端口并发送数据包,一次一个。恰好在数据包 nbr 105 处,连接关闭。 104 个数据包从 XMLPoller 发送并被服务器接收。 104 x 627 = 65208 字节。但是数据包 105,当发送的字节总数为 65835 时,连接关闭并出现此错误:

System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)

这是服务器上的错误。但是,我已经通过了 XMLPoller(客户端),我看到最后 627 个字节何时发送(因此发送直到 65835 个字节)并且我在客户端上没有看到任何错误,它顺利通过发送。

瑞典时间 20:15 更新

当我再调试一点时,我在客户端中也遇到了这个错误:

Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.

我想我已经确认在客户端中存在错误。我正在单步执行代码,在服务器上捕获任何异常之前,我在客户端上遇到了一个异常,如上所述。

/结束更新

在我看来,服务器从未收到它,出现上述错误。 由于客户端发生某些事情,服务器关闭了连接。但是,客户端的错误是在TCPInput;流读取数据由于某种原因已失效?

我没有在 MyNetworking.dll 中缓冲任何内容。

当我在套接字(在服务器上)上获得新连接时,我执行以下代码:

public void setConnected(Socket thisClient)
{
NetworkStream stream = new NetworkStream(thisClient);
socket = thisClient;
output = new TCPOutput(stream, outputHandler,this);
remoteIP = this.socket.RemoteEndPoint.ToString();
changeState(State.Connected);
try
{
stream.BeginRead(inputBuffer, 0, 5000, new AsyncCallback(OnDataReceived), null);
}
catch (Exception e)
{
this.disconnect();
}
}

然后是 OnDataReceived 方法(实际接收数据的地方):

public void OnDataReceived(IAsyncResult asyn)
{
int nbrRead = 0;
byte[] tmp = null;
try
{
nbrRead = stream.EndRead(asyn);
tmp = new byte[nbrRead];
}
catch (Exception e)
{
// *** HERE IS WHERE THE EXCEPTION IS CAUGHT ***
System.Diagnostics.Debugger.Log(0, "Bla1", e.ToString());
this.disconnect();
}
if (nbrRead > 0)
{
try
{
Array.Copy(inputBuffer, 0, tmp, 0, nbrRead);
}
catch(Exception e)
{
System.Diagnostics.Debugger.Log(0, "Bla2", e.ToString());
this.disconnect();
}
preProcessMessage(tmp);
try
{
stream.BeginRead(inputBuffer, 0, 5000, new AsyncCallback(OnDataReceived), new object());
}
catch(Exception e)
{
System.Diagnostics.Debugger.Log(0, "Bla3", e.ToString());
this.disconnect();
}
}
else
this.disconnect();

}

现在我对发生的事情一无所知......有什么想法吗?

更新 1:

发送数据的客户端代码:

public bool sendData(byte[] data)
{
if(this.state == State.Connected)
{
if (data != null && data.Length > 0)
{
try
{
//data = Crypto.Encrypt("a1s2d3", data);
outputStream.Write(data, 0, data.Length);
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine("ClientHandler.sendData> " + e.ToString());
}
//parent.outDataLog(data.Length);
}
}
return true;
}

更新2

我尝试对来自客户端的传出流进行刷新 - 无效:

public bool sendData(byte[] data)
{
if(this.state == State.Connected)
{
if (data != null && data.Length > 0)
{
try
{
//data = Crypto.Encrypt("a1s2d3", data);
outputStream.Write(data, 0, data.Length);
outputStream.Flush();
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine("ClientHandler.sendData> " + e.ToString());
}
//parent.outDataLog(data.Length);
}
}
return true;
}

更新 3:根据要求发布更多代码

我知道这个代码很旧,不是世界上最漂亮的东西。但它已经运行了 5 年,所以 =)

ClientHandler.cs(实际客户端用于发送等的内容)

using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace tWorks.tNetworking.tNetworkingCF
{
/// <summary>
/// Summary description for connectionHandler.
/// </summary>
public class ClientHandler
{
#region Fields (17) 

string address;
Connector connector;
DataHandler dataHandler;
int id;
TCPInput input;
int interval;
string localAddress;
IPEndPoint localPoint;
int localPort;
NetworkStream outputStream;
public TTCPClientInterface parent;
int port;
tWorks.tNetworking.Protocol.Protocol protocol;
bool reconnect;
string remoteIP;
Socket socket;
public State state;

#endregion Fields 

#region Enums (1) 

public enum State {Disconnected,Connecting,Connected}

#endregion Enums 

#region Constructors (4) 

public ClientHandler(int id, TTCPClientInterface parent, Socket socket, tWorks.tNetworking.Protocol.Protocol protocol)
{
this.id=id;
this.parent = parent;
this.protocol = protocol;
dataHandler = new DataHandler(protocol, this);
setConnected(socket);
}

public ClientHandler(int id, TTCPClientInterface parent, Protocol.Protocol protocol)
{
this.id=id;
this.parent = parent;
this.protocol = protocol;
dataHandler = new DataHandler(protocol, this);
state = State.Disconnected;
}

public ClientHandler(int id, TTCPClientInterface parent, Socket socket)
{
this.id=id;
this.parent = parent;
setConnected(socket);
}

public ClientHandler(int id, TTCPClientInterface parent)
{
this.id=id;
this.parent = parent;
this.protocol = null;
changeState(State.Disconnected);
}

#endregion Constructors 

#region Delegates and Events (4) 

// Delegates (2) 

public delegate void ConnectionLostDelegate(string message);
public delegate void exceptionDelegate(Exception ex);
// Events (2) 

public event exceptionDelegate ConnectionFailed;

public event ConnectionLostDelegate ConnectionLostEvent;

#endregion Delegates and Events 

#region Methods (17) 

// Public Methods (16) 

public void connect(string address, int port, int retryInterval, bool reestablish)
{
System.Random rand = new Random();
localPort = rand.Next(40000, 60000);
IPAddress localIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0]; // new IPAddress(Dns.GetHostByName(Dns.GetHostName()).AddressList[0].Address);
connect(address, port, retryInterval, reestablish, localIP.ToString(), localPort);
}

/// <summary>
/// Will connect to the address and port specified. If connection failed a new attempt will be made according to the Interval parameter.
/// If connection is lost attempts to reastablish it will be made if Reestablish is set to true.
/// </summary>
/// <param name="address"></param>
/// <param name="port"></param>
/// <param name="retryInterval"></param>
/// <param name="reestablish"></param>
public void connect(string address, int port, int retryInterval, bool reestablish, string localAddress, int localPort)
{
this.reconnect = reestablish;
this.address = address;
this.port = port;
this.interval = retryInterval;
this.localAddress = localAddress;
this.localPort = localPort;
changeState(State.Connecting);
connector = new Connector(address, port, this, interval, localPoint, reestablish);
connector.Connect();
}

public void disconnect()
{
reconnect = false;
if (connector != null)
{
connector.stopConnecting();
}
setDisconnected();
}

public void dispose()
{

}

public void failedConnect(Exception e)
{
if (ConnectionFailed != null)
ConnectionFailed(e);
}

public int getID()
{
return this.id;
}

public string getIP()
{
return remoteIP;
}

public bool isConnected()
{
return this.state == State.Connected;
}

public void outDataLog(int nbrBytes)
{
parent.outDataLog(nbrBytes, id);
}

public void preProcessMessage(byte[] data)
{
//data = Crypto.Decrypt("a1s2d3", data);
if(protocol != null)
dataHandler.addData(data);
else
processMessage(data);
}

public void processMessage(byte[] data)
{

parent.processMessage(data,this);
}

public bool sendData(byte[] data)
{
if(this.state == State.Connected)
{
if (data != null && data.Length > 0)
{
try
{
//data = Crypto.Encrypt("a1s2d3", data);
outputStream.Write(data, 0, data.Length);
outputStream.Flush();
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine("ClientHandler.sendData> " + e.ToString());
}
//parent.outDataLog(data.Length);
}
}
return true;
}

public void setConnected(Socket thisClient)
{
socket = thisClient;
outputStream = new NetworkStream(thisClient);
input = new TCPInput(outputStream, this);
remoteIP = this.socket.RemoteEndPoint.ToString();
changeState(State.Connected);
}

public void setDisconnected()
{
try
{
if (this.state == State.Connected)
{
changeState(State.Disconnected);
//socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
catch { }
if (reconnect)
this.connect(address, port, interval, true, localAddress, localPort);
}

public void stopConnect()
{
connector.stopConnecting();
changeState(State.Disconnected);
}

public override string ToString()
{
string returnString = "(D)";
if(this.state == State.Connected)
returnString = this.getIP();
return returnString;
}
// Private Methods (1) 

private void changeState(State state)
{
if (this.state == State.Connected && state == State.Disconnected)
{
if (ConnectionLostEvent != null)
ConnectionLostEvent("Uppkoppling bröts.");
}
this.state = state;
parent.connStateChange(this);
}

#endregion Methods 
}
}

这是 TCPInput.cs,它正在监听传入数据并将其转发给 ClientHandler(如上所示):

using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace tWorks.tNetworking.tNetworkingCF
{
public class TCPInput
{
NetworkStream stream;
ClientHandler client;

public TCPInput(NetworkStream nS, ClientHandler client)
{
stream = nS;
this.client = client;
Thread t = new Thread(new ThreadStart(run));
t.IsBackground = true;
t.Name = "TCPInput";
t.Start();
}

public void run()
{
bool continueRead = true;
byte[] readBuffer = new byte[32768];
byte[] receivedBuffer = null;

int nbrBytesRead = 0;
int receivedBufferPos = 0;
while(continueRead)
{
try
{
nbrBytesRead = 0;
nbrBytesRead = stream.Read(readBuffer, 0, 10000);
receivedBuffer = new byte[nbrBytesRead];
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("TCPInput> Exception when stream.Read: " + e.ToString());
continueRead = false;
}
if(nbrBytesRead > 0)
{
try
{
Array.Copy(readBuffer, 0, receivedBuffer, receivedBufferPos, nbrBytesRead);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("TCPInput> Exception when Array.Copy: " + e.ToString());
continueRead = false;
}
client.preProcessMessage(receivedBuffer);
}
else
{
// *** I can break here, the nbrOfBytes read is 0 when this whole thing explodes =)
System.Diagnostics.Debug.WriteLine("TCPInput> Number of bytes read == 0! Setting continueRead = false");
continueRead = false;
}

}
client.setDisconnected();
}
}
}

最佳答案

问题出在您的其他代码中,即“客户端”。它在发送所有“数据包”后关闭连接。您必须等到服务器收到所有这些。除了显式协商之外,一种简单的方法是等待服务器关闭连接。

关于C# 网络 : Server hangs after receiving more than 65535 bytes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4118800/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com