在同一台计算机上发送和接收两个节目之间的UDP数据包
题
时有可能得到两个单独的程序在同一台计算机上进行通信(仅单程)通过UDP通过本地主机/ 127 ...通过共享相同的端口#?
我们正在努力中,我们需要发送一个包含两台计算机之间的一些遥测UDP数据包一个学生项目。产生这些数据包的程序是专有的,但我使用工作的接收器程序自己用C#的 System.Net.Sockets.UdpClient 和 System.Net.IPEndPoint 的。
这工作在我们小组会议罚款时,我们必须连接多台计算机上,我们可以分别运行两个程序。但它不是非常有用,当我回家,并试图对遥测处理程序扩大,因为我只有一台电脑(我需要进行测试的处理程序中饲料)。我不能对任何学校的计算机上安装程序无论是。
当我尝试运行在同一时间在我的电脑上这两个程序(开始我的计划最后一个)我接收到一个SocketException说,只有一个使用的每个端口是的正常的允许。这使我相信一定有某种方式来分享端口(虽然是非常有意义的只有一个单一的程序可以在任何时间使用端口的计算机上,我有麻烦运行在同一时间多个互联网浏览器(和我假设他们使用端口80用于HTTP))。
的编辑的重新编辑:
sipwiz是正确的,并且由于为Kalmi指针UdpClient.Client.Bind()。 当时,虽然,我们正在使用生成类似的分组另一个程序考虑,以及我们能够使用与UDP客户端在构造函数结合我的第一个(尽管天真)的方式在同一台计算机上的共享端口。 对不起,不得不取消标记你的答案,sysrqb。
解决方案
我没想到这是可能的,但..好.. sipwiz 是正确的。
它可以很容易地完成。 (请投票sipwiz的答案了!)
IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);
//Failed try
try
{
var u = new UdpClient(5000);
u.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
UdpClient u2 = new UdpClient(5000);//KABOOM
u2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
catch (Exception)
{
Console.WriteLine("ERROR! You must call Bind only after setting SocketOptionName.ReuseAddress. \n And you must not pass any parameter to UdpClient's constructor or it will call Bind.");
}
//This is how you do it (kudos to sipwiz)
UdpClient udpServer = new UdpClient(localpt); //This is what the proprietary(see question) sender would do (nothing special)
//!!! The following 3 lines is what the poster needs...(and the definition of localpt (of course))
UdpClient udpServer2 = new UdpClient();
udpServer2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer2.Client.Bind(localpt);
其他提示
可以使用ReuseAddress插座选项多次绑定到端口。
UdpClient udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
您将需要设置服务器的UDP套接字上相同的选项。
下面是从由Tarnay卡尔曼和sipwiz答案的完整代码:
在服务器代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace UdpBroadcastTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Sender");
// This constructor arbitrarily assigns the local port number.
UdpClient udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Connect("localhost", 11000);
try
{
string message = String.Empty;
do
{
message = Console.ReadLine();
// Sends a message to the host to which you have connected.
Byte[] sendBytes = Encoding.ASCII.GetBytes(message);
udpClient.Send(sendBytes, sendBytes.Length);
} while (message != String.Empty);
udpClient.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("Press Any Key to Continue");
Console.ReadKey();
}
}
}
客户端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace UdpReciever
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Receiver");
// This constructor arbitrarily assigns the local port number.
UdpClient udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 11000));
try
{
//IPEndPoint object will allow us to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
string message = String.Empty;
do
{
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
message = Encoding.ASCII.GetString(receiveBytes);
// Uses the IPEndPoint object to determine which of these two hosts responded.
Console.WriteLine("This is the message you received: " +
message);
//Console.WriteLine("This message was sent from " +
// RemoteIpEndPoint.Address.ToString() +
// " on their port number " +
// RemoteIpEndPoint.Port.ToString());
}
while (message != "exit");
udpClient.Close();
//udpClientB.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("Press Any Key to Continue");
Console.ReadKey();
}
}
}
您也许能够将多个IP地址的网卡,或者回环上,并绑定在服务器和客户端不同的IP地址?
否则虚拟机的方法肯定会工作。
只有一个程序可以结合以每次一个端口。多个程序可以的 的连接到一个端口上的另一个系统的,而是被随机分配不同的网络浏览器都约束自己的本地端口。
除非你想要做一些丑陋的进程间通信或数据包嗅探,就没有办法有多个程序绑定到一个端口。
我的建议是:不要通过端口号到UdpClient构造函数。从href="http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.udpclient.aspx" rel="nofollow noreferrer">文档的绑定的到该端口(其中,作为sysrqb提到的,是不允许的)。 (如果你不这样做,我相信UdpClient将听取一个随机端口的任何答复的。你也可以挑选你知道是未使用的端口。)
在调用Connect()需要在端口号,服务器是通过听上。
发送者和接收者结合两种方案,即,在localhost.dats同一端口的简单的答案。
甚至改变你的代码,这样我可以在我得到它看来,你不能绑定到同一个端口,并且可以只使用一个端口相同的错误消息的IP地址传递 这里是我用你的榜样和改变它从我的本地机器捕捉我的IP示例代码.. 的IPAddress ip地址= Dns.Resolve(Dns.GetHostName())AddressList中[0]。 IPEndPoint ipLocalEndPoint =新IPEndPoint(ip地址,11000);
//IPEndPoint localpt = new IPEndPoint(ipLocalEndPoint);
UdpClient udpServer = new UdpClient(ipLocalEndPoint);
udpServer.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Connect(ipLocalEndPoint);
UdpClient udpServer2 = new UdpClient();
udpServer2.Client.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer2.Client.Bind(ipLocalEndPoint); // <<---------- Exception here
,这将产生对绑定()方法中的异常..对不起。