C#UdpClient.Receive函数不';t在任意数量的循环后返回
我正在为我的一个班级做一个基本的网络作业。目标是通过UDP将图像从一个程序发送到另一个程序。两个程序都在同一台电脑上运行,可以成功地在彼此之间发送字符串消息 为了发送图像,我将其从.bmp转换为名为C#UdpClient.Receive函数不';t在任意数量的循环后返回,c#,.net,networking,udp,udpclient,C#,.net,Networking,Udp,Udpclient,我正在为我的一个班级做一个基本的网络作业。目标是通过UDP将图像从一个程序发送到另一个程序。两个程序都在同一台电脑上运行,可以成功地在彼此之间发送字符串消息 为了发送图像,我将其从.bmp转换为名为ImageBytes的字节数组,然后将该数组分解为更小的“数据包”,并在将数据包数发送到服务器应用程序后将其发送到服务器应用程序: public void sendImage(ImageProcessor img) { int pSize = (Int16.MaxValue /
ImageBytes
的字节数组,然后将该数组分解为更小的“数据包”,并在将数据包数发送到服务器应用程序后将其发送到服务器应用程序:
public void sendImage(ImageProcessor img)
{
int pSize = (Int16.MaxValue / 2);
int numPackets = img.ImageBytes.Length / pSize;
int sizeLastPacket = img.ImageBytes.Length % pSize;
byte[][] packetArr = new byte[numPackets + 1][];
for (int i = 0; i < numPackets; i++)
{
packetArr[i] = new byte[pSize];
}
packetArr[numPackets] = new byte[sizeLastPacket];
for (int i = 0; i < numPackets; i++)
{
for (int j = 0; j < pSize; j++)
{
packetArr[i][j] = img.ImageBytes[j + pSize * i];
}
}
for (int i = 0; i < sizeLastPacket; i++)
{
packetArr[numPackets][i] = img.ImageBytes[numPackets * pSize + i];
}
sendDataAsString(numPackets + 1 + "");
for (int i = 0; i < numPackets; i++)
{
sendDataAsBytes(packetArr[i]);
}
sendDataAsBytes(packetArr[numPackets]);
}`
首先,我收到预期的数据包数量,然后调用for循环中的UdpClient.receive()
函数(包装在我自己的简单receiveDataAsBytes()
)函数
我正在发送的特定映像被分成28个数据包,但是,我的服务器应用程序只接收6个数据包,此时它被UdpClient.Receive()
函数阻止,好像它正在等待发送更多数据一样。没有抛出异常,我也不太明白为什么我的服务器应用程序在那个时候停止接收
我试图禁用Windows防火墙,但没有成功,并且通过发送多个字符串包测试了相同的代码。我发送了10个字符串包,我的服务器应用程序收到了它们。这个问题发生在我的台式机和笔记本电脑上
通过查看sendImage()
代码可以看出,所有28个数据包至少都被发送出去了,但是,我无法判断它们是否真的被receiveImage()
接收到,或者是否存在其他问题
编辑:以下是我分别为客户端应用程序和服务器应用程序编写的所有代码:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace NetDesignUDPClient
{
class MyUDPClient
{
#region Members
public byte[] IpAddr { get; set; }
public int RecPort { get; set; }
public int SendPort { get; set; }
public IPEndPoint RecEndPoint { get; set; }
public IPEndPoint SendEndPoint { get; set; }
public UdpClient MyClient { get; set; }
#endregion
#region Constructors
public MyUDPClient()
{
IpAddr = new byte[] { 127, 0, 0, 1 };
RecPort = 1101;
SendPort = 1100;
RecEndPoint = new IPEndPoint(new IPAddress(IpAddr), RecPort);
SendEndPoint = new IPEndPoint(new IPAddress(IpAddr), SendPort);
MyClient = new UdpClient(RecEndPoint);
connectToSendPort();
}
#endregion
#region Methods
public bool connectToSendPort()
{
try
{
MyClient.Connect(SendEndPoint);
return true;
}
catch (Exception ex)
{
// do something
return false;
}
}
public void sendDataAsString(string usrMsg)
{
byte[] sendMsg = Encoding.ASCII.GetBytes(usrMsg);
sendDataAsBytes(sendMsg);
}
public void sendDataAsBytes(byte[] msg)
{
MyClient.Send(msg, msg.Length);
}
public void sendImage(ImageProcessor img)
{
int pSize = (Int16.MaxValue / 2);
int numPackets = img.ImageBytes.Length / pSize;
int sizeLastPacket = img.ImageBytes.Length % pSize;
byte[][] packetArr = new byte[numPackets + 1][];
for (int i = 0; i < numPackets; i++)
{
packetArr[i] = new byte[pSize + 1];
}
packetArr[numPackets] = new byte[sizeLastPacket + 1];
for (int i = 0; i < numPackets; i++)
{
packetArr[i][0] = (byte)(i + 1); // Send packet number
for (int j = 1; j <= pSize; j++)
{
packetArr[i][j] = img.ImageBytes[j + pSize * i];
}
}
for (int i = 0; i < sizeLastPacket; i++)
{
packetArr[numPackets][i] = img.ImageBytes[numPackets * pSize + i];
}
sendDataAsString(numPackets + 1 + "");
for (int i = 0; i < numPackets; i++)
{
sendDataAsBytes(packetArr[i]);
}
sendDataAsBytes(packetArr[numPackets]);
}
public string receiveDataAsString(IPEndPoint sourcePoint)
{
return Encoding.ASCII.GetString(receiveDataAsBytes(sourcePoint));
}
public byte[] receiveDataAsBytes(IPEndPoint sourcePoint)
{
return MyClient.Receive(ref sourcePoint);
}
#endregion
}
}
使用系统;
使用系统文本;
Net系统;
使用System.Net.Sockets;
命名空间NetDesignUDPClient
{
类MyUDPClient
{
#区域成员
公共字节[]IpAddr{get;set;}
public int RecPort{get;set;}
公共int发送端口{get;set;}
公共IPEndPoint RecEndPoint{get;set;}
公共IPEndPoint SendEndPoint{get;set;}
公共UdpClient MyClient{get;set;}
#端区
#区域构造函数
公共MyUDPClient()
{
IpAddr=新字节[]{127,0,0,1};
RecPort=1101;
发送端口=1100;
RecEndPoint=新IPEndPoint(新IPAddress(IPAddress),RecPort);
SendEndPoint=新IPEndPoint(新IPAddress(IpAddr),发送端口);
MyClient=新的UdpClient(RecEndPoint);
connectToSendPort();
}
#端区
#区域方法
公共bool connectToSendPort()
{
尝试
{
连接(SendEndPoint);
返回true;
}
捕获(例外情况除外)
{
//做点什么
返回false;
}
}
public void sendDataAsString(字符串usrMsg)
{
字节[]sendMsg=Encoding.ASCII.GetBytes(usrMsg);
sendDataAsBytes(sendMsg);
}
公共无效sendDataAsBytes(字节[]msg)
{
MyClient.Send(msg,msg.Length);
}
public void sendImage(图像处理器img)
{
int pSize=(Int16.MaxValue/2);
int numPackets=img.ImageBytes.Length/pSize;
int-sizeLastPacket=img.ImageBytes.Length%pSize;
字节[][]packetArr=新字节[numPackets+1][];
对于(int i=0;i 对于(In j=1;j)您需要实现一个体面的协议。注意UDP是不可靠的。数据包可能或可能没有顺序或根本不存在。您必须考虑所有这些情况。这意味着,您需要确保,服务器能够检测出无序的数据包并重新排序它们,以及能够检测丢失的数据包和请求。询问他们。我在发送数据包时将数据包编号添加到每个数据包中。当我运行数据包时,服务器应用程序输出以下内容:创建的服务器实例。正在侦听…预期的数据包数量:28收到的数据包1,共28个,等待下一个数据包…收到的数据包2,共28个,等待下一个数据包…收到的数据包3,共28个,等待t他下一个…收到28个数据包中的第4个等待下一个…收到28个数据包中的第8个等待下一个…收到28个数据包中的第24个等待下一个…
这是丢弃数据包的迹象吗?当然是。至少是为了故障。但是如果其他数据包不能稍后到达,它们将被丢弃到某个地方。哪个这有点奇怪,因为两个程序都在同一台机器上运行。这可能是由时间问题引起的吗?如中所示,发送的数据包是否比服务器应用程序接收的数据包快?它始终接收数据包编号1、2、3和4,然后是数据包7或8、23或24。如果需要,我可以上载更多代码来绘制更清楚地了解情况,我会用更多的代码编辑我的原始帖子
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace NetDesignUDPClient
{
class MyUDPClient
{
#region Members
public byte[] IpAddr { get; set; }
public int RecPort { get; set; }
public int SendPort { get; set; }
public IPEndPoint RecEndPoint { get; set; }
public IPEndPoint SendEndPoint { get; set; }
public UdpClient MyClient { get; set; }
#endregion
#region Constructors
public MyUDPClient()
{
IpAddr = new byte[] { 127, 0, 0, 1 };
RecPort = 1101;
SendPort = 1100;
RecEndPoint = new IPEndPoint(new IPAddress(IpAddr), RecPort);
SendEndPoint = new IPEndPoint(new IPAddress(IpAddr), SendPort);
MyClient = new UdpClient(RecEndPoint);
connectToSendPort();
}
#endregion
#region Methods
public bool connectToSendPort()
{
try
{
MyClient.Connect(SendEndPoint);
return true;
}
catch (Exception ex)
{
// do something
return false;
}
}
public void sendDataAsString(string usrMsg)
{
byte[] sendMsg = Encoding.ASCII.GetBytes(usrMsg);
sendDataAsBytes(sendMsg);
}
public void sendDataAsBytes(byte[] msg)
{
MyClient.Send(msg, msg.Length);
}
public void sendImage(ImageProcessor img)
{
int pSize = (Int16.MaxValue / 2);
int numPackets = img.ImageBytes.Length / pSize;
int sizeLastPacket = img.ImageBytes.Length % pSize;
byte[][] packetArr = new byte[numPackets + 1][];
for (int i = 0; i < numPackets; i++)
{
packetArr[i] = new byte[pSize + 1];
}
packetArr[numPackets] = new byte[sizeLastPacket + 1];
for (int i = 0; i < numPackets; i++)
{
packetArr[i][0] = (byte)(i + 1); // Send packet number
for (int j = 1; j <= pSize; j++)
{
packetArr[i][j] = img.ImageBytes[j + pSize * i];
}
}
for (int i = 0; i < sizeLastPacket; i++)
{
packetArr[numPackets][i] = img.ImageBytes[numPackets * pSize + i];
}
sendDataAsString(numPackets + 1 + "");
for (int i = 0; i < numPackets; i++)
{
sendDataAsBytes(packetArr[i]);
}
sendDataAsBytes(packetArr[numPackets]);
}
public string receiveDataAsString(IPEndPoint sourcePoint)
{
return Encoding.ASCII.GetString(receiveDataAsBytes(sourcePoint));
}
public byte[] receiveDataAsBytes(IPEndPoint sourcePoint)
{
return MyClient.Receive(ref sourcePoint);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace NetDesignUDPServer
{
class UDPServer
{
#region Class members
public byte[] IpAddr { get; set; }
public int RecPort { get; set; }
public int SendPort { get; set; }
public IPEndPoint RecEndPoint { get; set; }
public IPEndPoint SendEndPoint { get; set; }
public UdpClient MyClient { get; set; }
#endregion
#region Constructors
public UDPServer()
{
IpAddr = new byte[] { 127, 0, 0, 1 };
RecPort = 1100;
SendPort = 1101;
RecEndPoint = new IPEndPoint(new IPAddress(IpAddr), RecPort);
SendEndPoint = new IPEndPoint(new IPAddress(IpAddr), SendPort);
MyClient = new UdpClient(RecEndPoint);
connectToSendPort();
}
#endregion
#region Methods
public bool connectToSendPort()
{
try
{
MyClient.Connect(SendEndPoint);
return true;
}
catch (Exception ex)
{
// do something
return false;
}
}
public string receiveDataAsString(IPEndPoint sourcePoint)
{
return Encoding.ASCII.GetString(receiveDataAsBytes(sourcePoint));
}
public byte[] receiveDataAsBytes(IPEndPoint sourcePoint)
{
return MyClient.Receive(ref sourcePoint);
}
public byte[] receiveImage(IPEndPoint sourcePoint)
{
List<byte> received = new List<byte>();
byte[] inBuffer;
int pCount;
int.TryParse(receiveDataAsString(sourcePoint), out pCount);
Console.WriteLine("Number of packets expected: " + pCount);
for (int i = 0; i < pCount; i++)
{
inBuffer = receiveDataAsBytes(sourcePoint);
Console.WriteLine("Received packet " + inBuffer[0] + " of " + pCount);
Console.WriteLine("Waiting for the next one...");
foreach (var val in inBuffer)
{
received.Add(val);
}
}
return received.ToArray();
}
public void sendDataAsString(string msg)
{
byte[] sendMsg = Encoding.ASCII.GetBytes(msg);
sendDataAsBytes(sendMsg);
}
public void sendDataAsBytes(byte[] msg)
{
MyClient.Send(msg, msg.Length);
}
public void sendImage(ImageProcessor img)
{
img.ConvertImageToBytes();
byte[] val = new byte[1];
for (int i = 0; i < img.ImageBytes.Length; i++)
{
val[0] = img.ImageBytes[i];
sendDataAsBytes(val);
}
val[0] = (byte)' ';
sendDataAsBytes(val);
}
#endregion
}