Tôi có một lớp máy chủ UDP không đồng bộ với một ổ cắm ràng buộc trên IPAddress.Any, và tôi muốn biết IPAddress gói nhận được đã được gửi đến (... hoặc nhận được trên). Có vẻ như tôi không thể chỉ sử dụng thuộc tính Socket.LocalEndPoint, vì nó luôn trả về 0.0.0.0 (có nghĩa là nó bị ràng buộc với điều đó ...).C# Ổ cắm UDP: Nhận địa chỉ người nhận
Dưới đây là những phần thú vị của mã Tôi hiện đang sử dụng:
private Socket udpSock;
private byte[] buffer;
public void Starter(){
//Setup the socket and message buffer
udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpSock.Bind(new IPEndPoint(IPAddress.Any, 12345));
buffer = new byte[1024];
//Start listening for a new message.
EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
}
private void DoReceiveFrom(IAsyncResult iar){
//Get the received message.
Socket recvSock = (Socket)iar.AsyncState;
EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
int msgLen = recvSock.EndReceiveFrom(iar, ref clientEP);
byte[] localMsg = new byte[msgLen];
Array.Copy(buffer, localMsg, msgLen);
//Start listening for a new message.
EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
//Handle the received message
Console.WriteLine("Recieved {0} bytes from {1}:{2} to {3}:{4}",
msgLen,
((IPEndPoint)clientEP).Address,
((IPEndPoint)clientEP).Port,
((IPEndPoint)recvSock.LocalEndPoint).Address,
((IPEndPoint)recvSock.LocalEndPoint).Port);
//Do other, more interesting, things with the received message.
}
Như đã đề cập trước đó này luôn in một dòng như:
nhận 32 byte từ 127.0.0.1:1678 để 0.0.0.0: 12345
Và tôi muốn nó trở thành một cái gì đó như:
nhận 32 byte từ 127.0.0.1:1678 để 127.0.0.1:12345
Cảm ơn, trước, đối với bất kỳ ý tưởng về vấn đề này! --Adam
CẬP NHẬT
Vâng, tôi tìm thấy một giải pháp, mặc dù tôi không thích nó ... Về cơ bản, thay vì mở một socket UDP đơn ràng buộc để IPAddress.Any, tôi tạo ra một ổ cắm duy nhất cho mọi IPAddress có sẵn. Vì vậy, chức năng khởi xướng mới trông giống như:
public void Starter(){
buffer = new byte[1024];
//create a new socket and start listening on the loopback address.
Socket lSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
lSock.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
EndPoint ncEP = new IPEndPoint(IPAddress.Any, 0);
lSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ncEP, DoReceiveFrom, lSock);
//create a new socket and start listening on each IPAddress in the Dns host.
foreach(IPAddress addr in Dns.GetHostEntry(Dns.GetHostName()).AddressList){
if(addr.AddressFamily != AddressFamily.InterNetwork) continue; //Skip all but IPv4 addresses.
Socket s = new Socket(addr.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
s.Bind(new IPEndPoint(addr, 12345));
EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
s.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, s);
}
}
Đây chỉ là để minh họa cho khái niệm, vấn đề lớn nhất với mã này như là, là mỗi ổ cắm đang cố gắng sử dụng cùng một bộ đệm ... mà nói chung là một ý tưởng tồi ...
Phải có giải pháp tốt hơn cho điều này; Ý tôi là, nguồn và đích là một phần của tiêu đề gói UDP! Oh well, tôi đoán tôi sẽ đi với điều này cho đến khi có một cái gì đó tốt hơn.
Nó đã được thử nghiệm bây giờ giao phối và nó hoạt động. Đây là câu trả lời tốt nhất cho một số câu hỏi về chủ đề này. Tôi rất muốn xem phiên bản ReceiveMessageFromAsync nhưng có lẽ có thể tự làm việc đó nếu bạn không trả lời. –
@StephenKennedy: Tôi không nghĩ rằng tôi thậm chí có mã đó xung quanh nữa, phải trung thực. : P Nó không phải là phức tạp khủng khiếp, mặc dù, IIRC; chỉ cần thiết lập một 'SocketAsyncEventArgs', đính kèm một trình xử lý vào sự kiện' Completed', sau đó chuyển đối tượng đó tới 'ReceiveMessageFromAsync'. – cHao
Không phải lo lắng. Tôi có SendToAsync() làm việc để có thể chơi với ReceiveMessageFromAsync() tmw :) Cảm ơn. –