C# 从同一套接字发送和接收数据的简单UDP示例
由于某些原因,我很难从同一个套接字发送和接收数据。总之,这是我的客户代码:C# 从同一套接字发送和接收数据的简单UDP示例,c#,udp,C#,Udp,由于某些原因,我很难从同一个套接字发送和接收数据。总之,这是我的客户代码: var client = new UdpClient(); IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy) client.Connect(ep); // send data client.Send(new byte[]
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy)
client.Connect(ep);
// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);
// then receive data
var receivedData = client.Receive(ref ep); // Exception: An existing connection was forcibly closed by the remote host
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening
client.Connect(ep);
// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);
// then receive data
var receivedData = client.Receive(ref ep);
Console.Write("receive data from " + ep.ToString());
Console.Read();
基本上,我想创建一个协议,在其中发送udp数据包,然后期望得到响应。就像每个请求都有一个响应的HTTP协议一样。如果服务器位于不同的计算机上,此代码也可以工作。不过,可能存在服务器和客户端位于同一台计算机上的情况
这是服务器:
UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);
while (true)
{
var groupEP = new IPEndPoint(IPAddress.Any, 11000); // listen on any port
var data = udpServer.Receive(ref groupEP);
udpServer.Send(new byte[] { 1 }, 1); // if data is received reply letting the client know that we got his data
}
编辑 我不能使用tcp的原因是,有时客户机位于NAT(路由器)后面,执行UDP打孔比tcp更简单
解决方案: 感谢markmnl回答以下是我的代码: 服务器:
UdpClient udpServer = new UdpClient(11000);
while (true)
{
var remoteEP = new IPEndPoint(IPAddress.Any, 11000);
var data = udpServer.Receive(ref remoteEP); // listen on port 11000
Console.Write("receive data from " + remoteEP.ToString());
udpServer.Send(new byte[] { 1 }, 1, remoteEP); // reply back
}
客户端代码:
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy)
client.Connect(ep);
// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);
// then receive data
var receivedData = client.Receive(ref ep); // Exception: An existing connection was forcibly closed by the remote host
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening
client.Connect(ep);
// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);
// then receive data
var receivedData = client.Receive(ref ep);
Console.Write("receive data from " + ep.ToString());
Console.Read();
(我假设您知道使用UDP(用户数据报协议)不能保证交付、检查重复项和拥塞控制,并且只会回答您的问题)
在您的服务器中,此行:
var data = udpServer.Receive(ref groupEP);
将groupEP
从您所拥有的重新分配到您收到某物的地址
这一行:
udpServer.Send(new byte[] { 1 }, 1);
将不起作用,因为您尚未指定将数据发送给谁。(它在您的客户端上工作,因为您调用了connect,这意味着send将始终发送到您连接到的端点,当然我们不希望在服务器上这样做,因为我们可能有许多客户端)。我想:
UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);
while (true)
{
var remoteEP = new IPEndPoint(IPAddress.Any, 11000);
var data = udpServer.Receive(ref remoteEP);
udpServer.Send(new byte[] { 1 }, 1, remoteEP); // if data is received reply letting the client know that we got his data
}
另外,如果服务器和客户端在同一台机器上,那么应该将它们放在不同的端口上。我会尽量简短地说,我在几个月前为我尝试构建的一个游戏做了一个UDP“客户端-服务器”连接,它的行为类似于TCP,您可以使用它发送(消息)(消息+对象)。我已经用它做了一些测试,它工作得很好,如果需要可以随意修改。这里是我的解决方案,定义远程和本地端口,然后将接收到的数据写入一个文件,将所有这些都放在您选择的类中,并使用正确的导入
static UdpClient sendClient = new UdpClient();
static int localPort = 49999;
static int remotePort = 49000;
static IPEndPoint localEP = new IPEndPoint(IPAddress.Any, localPort);
static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), remotePort);
static string logPath = System.AppDomain.CurrentDomain.BaseDirectory + "/recvd.txt";
static System.IO.StreamWriter fw = new System.IO.StreamWriter(logPath, true);
private static void initStuff()
{
fw.AutoFlush = true;
sendClient.ExclusiveAddressUse = false;
sendClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
sendClient.Client.Bind(localEP);
sendClient.BeginReceive(DataReceived, sendClient);
}
private static void DataReceived(IAsyncResult ar)
{
UdpClient c = (UdpClient)ar.AsyncState;
IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receivedBytes = c.EndReceive(ar, ref receivedIpEndPoint);
fw.WriteLine(DateTime.Now.ToString("HH:mm:ss.ff tt") + " (" + receivedBytes.Length + " bytes)");
c.BeginReceive(DataReceived, ar.AsyncState);
}
static void Main(string[] args)
{
initStuff();
byte[] emptyByte = {};
sendClient.Send(emptyByte, emptyByte.Length, remoteEP);
}
你们能把最后一句话扩展一下吗?若你们试着把一个套接字绑定到一个已经在使用的端口上,你们会得到一个地址已经在使用中的异常。但是,我看到您没有在客户端中为UdpClient指定端口,所以不用担心,您已经在使用另一个端口@ArteS如果您打算再次频繁地使用
UdpClient
,我将不会使用使用——每次处理和重新创建都是浪费。因此,很遗憾,我们不能使用使用s有帮助的sytatic sugar来为您处理垃圾,而且必须自己处理。嗯,这不是UDP,您知道,这是UDP之上的协议。我碰巧非常了解,我已经在UDP之上编写了协议,以实现可靠性。从2021年1月20日起,链路中断