我决定看看网络消息等,我的第一个呼叫端口是UDP .
我遇到的问题是当我尝试发送消息时 . 我试图在特定端口上命中IP,但应用程序错误与错误
“SocketException远程主机强行关闭现有连接” .
这是代码 .
User ME = new User();
UdpClient MyUDPClient;
private void Form1_Load(object sender, EventArgs e)
{
ME.Username = Environment.UserName;
}
private void StartUDP_Click(object sender, EventArgs e)
{
CreateUDPClient();
}
private void CreateUDPClient()
{
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
int Port = int.Parse(txt_Port.Text);
ME.UserIP = new IPEndPoint(ip, Port);
break;
}
}
MyUDPClient = new UdpClient(ME.UserIP);
UDPListening();
}
public void UDPListening()
{
MyUDPClient.BeginReceive(ReceiveMessage, new object());
}
private void ReceiveMessage(IAsyncResult IAR)
{
byte[] B = MyUDPClient.EndReceive(IAR, ref ME.UserIP);
ProcessMSG(Encoding.ASCII.GetString(B));
UDPListening();
}
delegate void MessageDelegate(String MSG);
public void ProcessMSG(String M)
{
if (this.lbl_Messages.InvokeRequired)
{
MessageDelegate Del = new MessageDelegate(ProcessMSG);
this.Invoke(Del, M);
}
else
{
lbl_Messages.Text = M;
}
}
//Send Data to Another version of this program elsewhere.
private void btn_SendtoTarget_Click(object sender, EventArgs e)
{
IPEndPoint TargetIP = new IPEndPoint(IPAddress.Parse(txt_Send2IP.Text),int.Parse(txt_Send2Port.Text));
byte[] Message = Encoding.ASCII.GetBytes("TEST TEST TEST");
MyUDPClient.Send(Message, Message.Length, TargetIP);
}
}
谢谢您的帮助 .
不确定这是否有帮助,但......
应用程序正在机器上运行,设置为侦听在192.168.0.25:5555
发送正试图发送到机器192.168.0.50:10001
T.
从进一步阅读,我认为我的具体问题是创建UDPclient对象 . 它已创建,然后正在侦听ip 192.168.0.25:5555 . 当我尝试发送消息时,我试图使用相同的UDPClient但发送到新的IP . 我得到的感觉这不是正确的程序,因此它试图关闭前一个下来???我相信有人可以证实这一点 . 所以这对我来说,要有效的UDP网络(UP和Down),我需要有一个UDP客户端接收和第二个UDP能够发送(这是我想要命中的每个目标地址的动态) . 这一切都是猜测工作,如果我有这个,我希望有人可以提供一些指示 .
1 回答
以上几个问题 .
不要在C#中使用
ME
,它是this
.Me
是VB . 如果使用C#,上面的代码将无法编译,因为您省略了您定义为ME
的User()
类 . 我不确定你为什么认为你需要那个,因为它似乎只有UserIP
和UserName
. IP是Socket
的一部分,因此如果您需要它,您应该使用它:IPAddress ip = IPAddress.Parse(socket.RemoteEndPoint);
并且
UserName
可以成为全局字符串变量 - 不必是类的一部分 .也许我看到
User()
对象中的任何一个变量都需要这样的东西,并且只是为了解决这些问题,对我来说,试图破译代码 .始终定义
Socket
,连接到它,然后执行.Send()
. 您错过了按钮点击的前两个步骤 - 您只需执行.Send()
.UdpClient
不是Socket
,我认为最好将此作为Socket
并稍后定义您的连接类型 . 我认为你是正确的,你正试图使用你定义为你的听众的UdpClient
来做你的 . 不要在发送和收听时使用相同的对象!通常你会,但每个事件有2个不同的地址和端口 .不要在
CreateUDPClient()
函数中使用foreach
来让IPAddress
分配给IPEndPoint
. 你已经知道你的IP了 . 直接分配 . 这是浪费处理时间 .如果您只有主机名,则可以:
不要使用
Dns.GetHostEntry()
- 如果该名称没有反向查找(PTR)记录,它将失败 . 使用Dns.GetHostAddresses()
. 我不知道为什么你认为你需要循环,除非你有你提供的相同主机名的IPv6地址 . 如果没有,只需使用[0]
- 如果不使用IPv6,它应该是您将要使用的第一个也是唯一的IP . 但是,再次,因为你已经有了IP,只需将其插入即可 - 无需进行查找 . 它也可以帮助你消除Dns.GetHostName()
- 只需使用192.168.0.25
.供您参考,MSDN在此处有一个同步套接字发送/接收的过程:https://msdn.microsoft.com/en-us/library/kb5kfec7(v=vs.110).aspx
和异步套接字在这里发送/接收:
http://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx
由于我只鄙视链接答案,并且您似乎通过分别使用
Send()
和EndReceive()
将这两种方法混合到上面的链接中,我将尽力简洁地描述其内容并帮助修复您的代码:基本上他们说要使用
StateObject
类,而不是全局变量MyUDPClient
:您将创建一个套接字并将其添加到该套接字 . 缓冲区用于告诉
Receive()
或EndReceive()
您希望一次从响应中读回的块的大小,sb
将用作响应的占位符 .看起来你在这里有很多事情要做:从表格和听众那里进行一次性测试 . 您的
SendtoTarget
按钮执行同步发送,StartUDP_Click()
执行异步接收 .您可以将
SendtoTarget_Click()
事件更改为此( never defined your socket, before, and you must connect to it before sending ):对于您的听众,您可以:
和你的函数叫
ReceiveMessage()
,这样做:尽我所能以适当的方式将您的代码与MSDN集成 . 您可能能够将该套接字分配给
StateObject
并再次调用BeginReceive()
- 不确定 . 但是不要像那样重复使用UdpClient
对象 . 像在MSDN上一样使用StateObject
类,并仅将其用作您的侦听器 .