TCP 接收没有 return 预期的字节数
TCP Receive does not return expected number of bytes
我使用 TCPIP 从控制器获取数据。当使用TCPIP接收数据时,我只能得到第一行数据,这意味着数据长度是1514,但另一行长度为174的数据无法从C#的TCPIP客户端协议中获取。可能需要你们就此提出建议。
下图是使用Wireshark跟踪TCPIP数据
下图是从TCPIP客户端协议接收数据的方法。
谢谢。
以下是我如何通过 TCPIP 连接和获取数据。如有错误请指正
public void Connect(string ipAddress, int port)
{
lock (this)
{
try
{
IPAdddress = ipAddress;
Port = port;
IPAddress ip = IPAddress.Parse(ipAddress);
IPEndPoint endPoint = new IPEndPoint(ip, port);
Client.BeginConnect(endPoint, new AsyncCallback(OnClientConnected), null);
}
catch (Exception ex)
{
ExceptionThrownEventArgs args = new ExceptionThrownEventArgs();
args.Exception = ex;
if (m_ExceptionThrown != null)
{
foreach (Delegate del in m_ExceptionThrown.GetInvocationList())
{
ISynchronizeInvoke syncer = del.Target as ISynchronizeInvoke;
if (syncer == null)
{
del.DynamicInvoke(this, args);
}
else
{
syncer.BeginInvoke(del, new object[] { this, args });
}
}
#endregion
}
// SupportMethod.ShowExceptionMessage(ex, Output.EventLog);
}
}
}
private void OnMessageReceived(IAsyncResult result)
{
try
{
Metadata metadata = (Metadata)result.AsyncState;
if (metadata.ReceiveBuf[0] == 0)
{
Disconnect();
}
else
{
Client.EndReceive(result);
var e = Encoding.GetEncoding("iso-8859-1");
LastMessageReceived = e.GetString(metadata.ReceiveBuf).Trim('[=11=]');
Debug.Print("TCPRaw: " + LastMessageReceived);
if (m_EchoOnReceived)
{
Echo(LastMessageReceived);
}
MessageReceivedEventArgs args = new MessageReceivedEventArgs();
if (m_MessageReceived != null)
{
#region Fire the MessageReceived event (bound during instantiation of ClientSocket).
foreach (Delegate del in m_MessageReceived.GetInvocationList())
{
ISynchronizeInvoke syncer = del.Target as ISynchronizeInvoke;
if (syncer == null)
{
del.DynamicInvoke(this, args);
}
else
{
syncer.BeginInvoke(del, new object[] { this, args });
}
}
#endregion
}
// Provide additional data for the socket operation. Re-instantiate a new Metadata object.
metadata = new Metadata();
metadata.ReceiveBuf = new byte[m_ReceiveBufSize];
// Continue to prepare receive data from the connected Server.
Client.BeginReceive(
metadata.ReceiveBuf,
0,
metadata.ReceiveBuf.Length,
SocketFlags.None,
new AsyncCallback(OnMessageReceived),
metadata);
}
}
catch (Exception ex)
{
ExceptionThrownEventArgs args = new ExceptionThrownEventArgs();
args.Exception = ex;
// ExceptionThrown Event.
if (m_ExceptionThrown != null)
{
#region Fire the ExceptionThrown event (bound during instantiation of ClientSocket).
// Check the Target of each delegate in the event's invocation list, and marshal the call
// to the target thread if that target is ISynchronizeInvoke
// ref:
foreach (Delegate del in m_ExceptionThrown.GetInvocationList())
{
ISynchronizeInvoke syncer = del.Target as ISynchronizeInvoke;
if (syncer == null)
{
del.DynamicInvoke(this, args);
}
else
{
syncer.BeginInvoke(del, new object[] { this, args });
}
}
#endregion
}
// SupportMethod.ShowExceptionMessage(ex, Output.EventLog);
}
}
对于TCP/IP,当你在Receive方法中指定接收的字节数时,它是一个上限,而不是绝对字节数。如果您收到的字节数少于请求的字节数,则需要进行另一次读取并将结果组合成您想要的数据。这就是为什么 Receive 方法允许您在数组中指定索引以放置接收到的数据。例如:
var message = new byte[myMessageSize];
var totalBytesReceived = 0;
while (totalBytesReceived < myMessageSize)
{
var bytesReceived = socket.Receive(message,
totalBytesReceived,
myMessageSize - totalBytesReceived,
SocketFlags.None);
totalBytesReceived += bytesReceived;
}
我建议不要使用 BeginReceive,回调很难管理,而且大多数人都做错了。使用同步方法或 ReceiveAsync()。
我使用 TCPIP 从控制器获取数据。当使用TCPIP接收数据时,我只能得到第一行数据,这意味着数据长度是1514,但另一行长度为174的数据无法从C#的TCPIP客户端协议中获取。可能需要你们就此提出建议。
下图是使用Wireshark跟踪TCPIP数据
下图是从TCPIP客户端协议接收数据的方法。
谢谢。
以下是我如何通过 TCPIP 连接和获取数据。如有错误请指正
public void Connect(string ipAddress, int port)
{
lock (this)
{
try
{
IPAdddress = ipAddress;
Port = port;
IPAddress ip = IPAddress.Parse(ipAddress);
IPEndPoint endPoint = new IPEndPoint(ip, port);
Client.BeginConnect(endPoint, new AsyncCallback(OnClientConnected), null);
}
catch (Exception ex)
{
ExceptionThrownEventArgs args = new ExceptionThrownEventArgs();
args.Exception = ex;
if (m_ExceptionThrown != null)
{
foreach (Delegate del in m_ExceptionThrown.GetInvocationList())
{
ISynchronizeInvoke syncer = del.Target as ISynchronizeInvoke;
if (syncer == null)
{
del.DynamicInvoke(this, args);
}
else
{
syncer.BeginInvoke(del, new object[] { this, args });
}
}
#endregion
}
// SupportMethod.ShowExceptionMessage(ex, Output.EventLog);
}
}
}
private void OnMessageReceived(IAsyncResult result)
{
try
{
Metadata metadata = (Metadata)result.AsyncState;
if (metadata.ReceiveBuf[0] == 0)
{
Disconnect();
}
else
{
Client.EndReceive(result);
var e = Encoding.GetEncoding("iso-8859-1");
LastMessageReceived = e.GetString(metadata.ReceiveBuf).Trim('[=11=]');
Debug.Print("TCPRaw: " + LastMessageReceived);
if (m_EchoOnReceived)
{
Echo(LastMessageReceived);
}
MessageReceivedEventArgs args = new MessageReceivedEventArgs();
if (m_MessageReceived != null)
{
#region Fire the MessageReceived event (bound during instantiation of ClientSocket).
foreach (Delegate del in m_MessageReceived.GetInvocationList())
{
ISynchronizeInvoke syncer = del.Target as ISynchronizeInvoke;
if (syncer == null)
{
del.DynamicInvoke(this, args);
}
else
{
syncer.BeginInvoke(del, new object[] { this, args });
}
}
#endregion
}
// Provide additional data for the socket operation. Re-instantiate a new Metadata object.
metadata = new Metadata();
metadata.ReceiveBuf = new byte[m_ReceiveBufSize];
// Continue to prepare receive data from the connected Server.
Client.BeginReceive(
metadata.ReceiveBuf,
0,
metadata.ReceiveBuf.Length,
SocketFlags.None,
new AsyncCallback(OnMessageReceived),
metadata);
}
}
catch (Exception ex)
{
ExceptionThrownEventArgs args = new ExceptionThrownEventArgs();
args.Exception = ex;
// ExceptionThrown Event.
if (m_ExceptionThrown != null)
{
#region Fire the ExceptionThrown event (bound during instantiation of ClientSocket).
// Check the Target of each delegate in the event's invocation list, and marshal the call
// to the target thread if that target is ISynchronizeInvoke
// ref:
foreach (Delegate del in m_ExceptionThrown.GetInvocationList())
{
ISynchronizeInvoke syncer = del.Target as ISynchronizeInvoke;
if (syncer == null)
{
del.DynamicInvoke(this, args);
}
else
{
syncer.BeginInvoke(del, new object[] { this, args });
}
}
#endregion
}
// SupportMethod.ShowExceptionMessage(ex, Output.EventLog);
}
}
对于TCP/IP,当你在Receive方法中指定接收的字节数时,它是一个上限,而不是绝对字节数。如果您收到的字节数少于请求的字节数,则需要进行另一次读取并将结果组合成您想要的数据。这就是为什么 Receive 方法允许您在数组中指定索引以放置接收到的数据。例如:
var message = new byte[myMessageSize];
var totalBytesReceived = 0;
while (totalBytesReceived < myMessageSize)
{
var bytesReceived = socket.Receive(message,
totalBytesReceived,
myMessageSize - totalBytesReceived,
SocketFlags.None);
totalBytesReceived += bytesReceived;
}
我建议不要使用 BeginReceive,回调很难管理,而且大多数人都做错了。使用同步方法或 ReceiveAsync()。