- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个客户端和服务器,都有接收和发送方法,并且都使用相同的数据包类、数据包头大小和反序列化等。
如果我只发送较小的文本消息包,一切正常,但是当我尝试发送图像时,缓冲区溢出并且出现内存不足异常。奇怪的是,它实际上从数据包的头部找到了正确的数据包大小,但是当它继续读取数据包大小时,数据包大小变成了奇数。图像在数据包类中以字节数组的形式存在。
在即将读取实际数据包的部分,PacketLength 已更改为非常大的数字或什至为负值。我试图理解为什么尽管不再寻找 header 大小它仍会不断变化..
我确保服务器只发送 1 个包,我还在发送前打印包大小,然后检查客户端是否收到所述包。客户不断收到超出应有的金额。
请帮帮我:)
服务器在发送过程中打印的内容:
客户端接收时打印出来的内容:
(然后一旦读取了整个数据包,它就会被添加到一个列表中并转发到其他内部方法以根据其类型(图像、文本等)处理数据包
数据包中嵌入图像的示例:
服务器代码:
// This is a threaded TCPclient handler on the server.
private void _TCP_ManageClient(object clientObj)
{
uint clientID = _ClientConnected();
var client = (TcpClient) clientObj;
bool connected = true;
_AddClientFromList(ref client, clientID);
NetworkStream stream = client.GetStream();
AddPacketToSend(_Packet_Welcome(clientID)); // Welcome, client #X. message is sent out.
while (connected)
{
// S E N D P A C K E T
SendPacketsInQueue(stream);
if (stream.DataAvailable)
{
// R E C E I V E P A C K E T
ReceivePacketsFromStream(stream);
// R E A D P A C K E T
ReadPacketsInQueue(ref connected);
}
}
if (!connected) { Con.Add(m_Logtag, "Client[" + clientID + "] dropped"); }
}
// Send packets which are in the format of 'RemuseNetPacket' class.
public void SendPacketsInQueue(NetworkStream stream)
{
if (m_SendMessageList.Count > 0)
{
byte[] packetBytes;
byte[] readyData;
int byteCount = 0;
int sentPackets = 0;
for (int i = 0; i < m_SendMessageList.Count; i++)
{
packetBytes = m_SendMessageList[i].Serialize();
Int32 headersize = packetBytes.Length;
byte[] packetLength = BitConverter.GetBytes(headersize);
Con.Add(m_Logtag, "Header size: " + headersize);
Con.Add(m_Logtag, "PacketLength: " + packetLength.Length);
readyData = Extensions.Concatenate(packetLength, packetBytes);
stream.Write(readyData, 0, readyData.Length);
byteCount += readyData.Length;
sentPackets++;
}
Con.Add(m_Logtag, "Sent " + sentPackets + "/" + m_SendMessageList.Count + " packets (" + byteCount + " bytes)");
int r = m_SendMessageList.Count;
m_SendMessageList.Clear();
Con.Add(m_Logtag, "Removed " + r + " sent packages from list");
}
}
客户端代码:
// This is the client's TCP loop.
private void _TCPClientStart()
{
try
{
TCPClient = new TcpClient();
TCPClient.Connect(m_HostIP, m_Port);
Con.Add(m_Logtag, "Connected to " + m_HostIP + ":" + m_Port);
m_IsRunning = true;
m_Connected = true;
NetworkStream stream = TCPClient.GetStream();
AddPacketToSend(_Packet_Hello()); // Hello, I am [computer name]. message is sent out.
while (m_Connected)
{
if (stream.DataAvailable)
{
// R E C E I V E P A C K E T
ReceivePacketsFromStream(stream);
// R E A D P A C K E T
ReadPacketsInQueue();
}
// S E N D P A C K E T
SendPacketsInQueue(stream);
}
Disconnect();
}
catch (Exception e)
{
Con.Add(m_Logtag, "TCPclient Exception: " + e.ToString());
Con.Add(m_Logtag, "Stacktrace: " + e.StackTrace);
}
}
// Client receives a packet.
private void ReceivePacketsFromStream(NetworkStream stream)
{
int PacketLength = -1;
int BytesRead = 0;
byte[] ReceivedBytes = new byte[0];
while (stream != null && stream.DataAvailable)
{
// Read packet's header (first 4 bytes)
if (PacketLength < 0)
{
if (BytesRead == 0) { ReceivedBytes = new byte[m_HeaderLength]; }
BytesRead += stream.Read(ReceivedBytes, BytesRead, (ReceivedBytes.Length - BytesRead));
if (BytesRead == m_HeaderLength)
{
PacketLength = BitConverter.ToInt32(ReceivedBytes, 0);
// Obtained information about the packet's size.
if (PacketLength < m_MaxPacketSize)
{
Con.Add(m_Logtag, "Received packet header, packet size: " + PacketLength);
BytesRead = 0;
Array.Clear(ReceivedBytes, 0, ReceivedBytes.Length);
}
else
{
Con.Add(m_Logtag, "Received too big packet: " + PacketLength);
}
}
}
// Start reading packet content.
else
{
Con.Add(m_Logtag, "Start reading packet");
if (BytesRead == 0) { ReceivedBytes = new byte[PacketLength]; }
BytesRead += stream.Read(ReceivedBytes, BytesRead, (ReceivedBytes.Length - BytesRead));
// Whole packet obtained.
if (BytesRead >= PacketLength)
{
RemuseNetPacket packet = new RemuseNetPacket();
packet = packet.Desserialize(ReceivedBytes);
Con.Add(m_Logtag, "Received packet #" + packet.ID);
// Add packet to list for reading.
if (packet != null) { AddPacketToRead(packet); }
BytesRead = 0;
PacketLength = -1;
Array.Clear(ReceivedBytes, 0, ReceivedBytes.Length);
}
}
}
}
编辑:添加图片包类型代码
private RemuseNetPacket _Packet_Screen()
{
Con.Add(m_Logtag, "Send Image packet");
RemuseNetPacket p = new RemuseNetPacket();
p.Type = RemusePacketType.Image;
// captures the screen with the mouse (true) using format jpeg.
p.Data = ScreenCapture.CaptureToBytes(true, m_ImageFormat);
Con.Add(m_Logtag, "package img size: " + p.Data.Length);
p.SenderName = m_Name;
p.Timestamp = _GetCurrentTimestamp();
return p;
}
这是日志中关于奇怪的数据包大小的内容:
[Active] Host: Send Image packet (this is where i sent 1 image packet)
[Active] Host: removed 1 sent packages from list
[Active] Client: Start reading packet
[Active] Client: Received data: 74456 / 327332 (this is the actual packet size)
[Active] Client: Received packet header, packet size: -251848753 (suddenly it becomes this..)
[Active] Client: Start reading packet
[Active] Client: Received data: 4 / 1251185707
[Active] Client: Received data: 4 / 1251185707
[Active] Client: Received data: 4 / 1251185707
[Active] Client: Received data: 4 / 1251185707
[Active] Client: Received data: 4 / 1251185707
[Active] Client: Received data: 4 / 1251185707
最佳答案
很难具体诊断,但对于这种情况,这是一个更典型的读取循环;更简单并且可能更容易调试:
byte[] buffer = new byte[512];
while(true) {
if(!Fill(stream, buffer, 4)) break;
int len = BitConverter.ToInt32(buffer, 0);
if(buffer.Length < len) buffer = new byte[len]; // need moar!
if(!Fill(stream, buffer, len)) throw new EndOfStreamException();
ProcessData(buffer, len); // note: only look at the first "len" bytes
}
static bool Fill(Stream source, byte[] destination, int count) {
int bytesRead, offset = 0;
while(count > 0 &&
(bytesRead = source.Read(destination, offset, count)) > 0)
{
offset += bytesRead;
count -= bytesRead;
}
return count == 0;
}
关于C# TCPClient 流问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37783817/
要关闭 TcpClient,必须关闭流。通常的做法是: client.GetStream().Close(); client.Close(); 因此仅使用 client
我正在阅读 the documentation on TcpClient.Close()并注意到这一点: Calling this method will eventually result in t
用于同步消息交换的我的客户端类: public class AsClient { private TcpClient connection; public AsClient(int s
我正在制作一个向许多 TCP 监听器发送数据的程序。如果不再使用其中一个 TCP 发送 channel ,我们是否需要使用 TCPClient.close 将其关闭。如果我们让它打开会怎样? 谢谢!
.NET 允许两种非常相似的方式从网络“读取”(假设 TCP 连接): 1. TcpClient.GetStream().Read() 2. TcpClient.Client.Receive() 通过
我找到了一些关于如何用 C# 编写 TCP/IP 客户端-服务器应用程序的代码服务器 Main 以此开头: TcpListener serverSocket = new TcpListener(888
我正在尝试连接到本地网络内的路由器。到目前为止,我已经使用了 TcpClient。 检查我的代码: public static void RouterConnect() {
服务器 : public class TcpServer { private TcpListener tcpListener; private static ManualResetEv
我想使用 TcpClient 发送 HTTP 请求。考虑以下代码: byte[] buf = new byte[1024]; string header = "GET
我在半关闭 TcpClient 时遇到了严重问题。我想做的是: 在客户端: 发送消息 关闭用于发送的底层套接字 收到回复 关闭用于读取的底层套接字(或者,此时,直接关闭它) 在服务器上: 接收消息 关
我有一个客户端和服务器,都有接收和发送方法,并且都使用相同的数据包类、数据包头大小和反序列化等。 如果我只发送较小的文本消息包,一切正常,但是当我尝试发送图像时,缓冲区溢出并且出现内存不足异常。奇怪的
在我的 C# 应用程序中,我有一个线程,它基本上不断地从 TcpClient 读取数据,直到被告知停止。为此,我使用 WaitHandles,例如: private ManualResetEvent
我有一个客户端-服务器程序。 我正在发送这样的数据: private void Sender(string s,TcpClient sock) { try { byte[] b
这个问题在这里已经有了答案: C# network connection running from shared drive (1 个回答) 关闭 7 年前。 我几天前问过类似的问题。那时,我正在尝
我有一个 TCPClient,它创建一个流,当 DataAvailable 时我从中读取流。 每 20 秒 !DataAvailable 我会使用 ACK 消息对套接字执行 ping 操作,以防止流关
我正在使用 SwifSockets:https://github.com/swiftsocket/SwiftSocket :按照有关如何使用它的说明后,我在堆栈溢出上找到了此代码:Sending Me
我在继承的一些代码中有一个奇怪的行为 - 下面的简化示例演示了如果内置到普通控制台应用程序中的问题。 WhoIs 在第 5 次调用时达到其使用限额 - 并返回一条消息 + 关闭套接字。使用 ReadL
我正在用 C# 开发一个 Tcp 客户端,我正在使用 TcpClient 类。我无法连接到服务器。 调试应用程序我可以看到对 Connect 的调用是成功的,但是在我这样做之后,我用 netstat
我有一个我似乎无法弄清楚的问题,请帮忙。我创建了一个类来处理使用 TcpClient 的某些硬件的接口(interface)。我希望此类在 HW 被销毁之前向 HW 发送最后一个命令。 为了解决这个问
您好,感谢您的帮助。这次想问一下TcpClient。我有一个服务器程序,我正在编写一个客户端程序。此客户端使用 TcpClient。首先是创建一个新客户端 clientSocket=new TcpCl
我是一名优秀的程序员,十分优秀!