C# UDP套接字无法接收消息
C# UDP socket unable to receive message
我无法从 UDP 套接字接收消息。
我制作了运行良好的 C++ 服务器和客户端应用程序。服务器从客户端接收消息然后发回响应,客户端接收消息然后他们都关闭套接字并退出。现在我尝试用 C# 创建客户端程序,但我无法从服务器接收消息。客户端 C# 应用程序发送消息,然后 C++ 服务器正确接收它,但是当服务器发回他的响应时,客户端无法接收它。我已经在本地虚拟机和 VPS 上测试了我的服务器,结果是一样的。有什么想法吗?
服务器代码 C++:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <pthread.h>
#define MSG "Hi i'm server"
#define SERVERPORT "8642"
#define MAXBUFLEN 100
// Get sockaddr, IPv4 or IPv6.
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int LoginUser()
{
int locUserId = 0;
// Call DB.
return 0;
}
int main(int argc, char *argv[])
{
// Load up address structs.
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // Use IPv4 or IPv6, whichever.
hints.ai_socktype = SOCK_DGRAM; // UDP.
hints.ai_flags = AI_PASSIVE; // Fill in my IP for me.
int locInitAddrInfo = getaddrinfo(NULL, SERVERPORT, &hints, &res);
if (locInitAddrInfo != 0)
{
printf("Error initialize address info: %s\n", gai_strerror(locInitAddrInfo));
return 1;
}
printf("Address info initialized: %i\n", locInitAddrInfo);
// Initialize the socket.
int locInitSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (locInitSocket == -1)
{
printf("Error initialize socket: %s\n", strerror(errno));
freeaddrinfo(res);
return 2;
}
printf("Socket initialized: %i\n", locInitSocket);
// Bind a name to a socket.
int locInitBind = bind(locInitSocket, res->ai_addr, res->ai_addrlen);
if (locInitBind == -1)
{
printf("Error bind socket: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 3;
}
printf("Socket binded: %i\n", locInitBind);
// Receive message from client.
char buf[MAXBUFLEN];
struct sockaddr_storage their_addr;
socklen_t addr_len = sizeof their_addr;
int locNumByteRecv = recvfrom(locInitSocket, buf, MAXBUFLEN, 0, (struct sockaddr *)&their_addr, &addr_len);
if (locNumByteRecv == -1)
{
printf("Error receive from: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 4;
}
// -----------------------------------------
char s[INET6_ADDRSTRLEN];
printf("Server: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
printf("Server: packet is %d bytes long\n", locNumByteRecv);
buf[locNumByteRecv] = '[=10=]';
printf("Server: packet contains \"%s\"\n", buf);
// -----------------------------------------
sleep(2);
// Send to client.
int locNumByteSend = sendto(locInitSocket, MSG, strlen(MSG), 0, (struct sockaddr *)&their_addr, addr_len);
if (locNumByteSend == -1)
{
printf("Error send to: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 5;
}
printf("Server: sent %d bytes to %s:%s\n", locNumByteSend, inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s), SERVERPORT);
// Free the linked-list.
freeaddrinfo(res);
// Close the socket.
close(locInitSocket);
printf("Socket closed.\nHave a nice day :)\n");
return 0;
}
客户端代码 C++:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MSG "Hi i'm client"
#define SERVERIP "192.168.1.33"
#define SERVERPORT "8642"
#define MAXBUFLEN 100
// Get sockaddr, IPv4 or IPv6.
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int argc, char *argv[])
{
// Load up address structs.
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // Use IPv4 or IPv6, whichever.
hints.ai_socktype = SOCK_DGRAM; // UDP.
int locInitAddrInfo = getaddrinfo(SERVERIP, SERVERPORT, &hints, &res);
if (locInitAddrInfo != 0)
{
printf("Error initialize address info: %s\n", gai_strerror(locInitAddrInfo));
return 1;
}
printf("Address info initialized: %i\n", locInitAddrInfo);
// Initialize the socket.
int locInitSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (locInitSocket == -1)
{
printf("Error initialize socket: %s\n", strerror(errno));
freeaddrinfo(res);
return 2;
}
printf("Socket initialized: %i\n", locInitSocket);
// Send to server.
int locNumByteSend = sendto(locInitSocket, MSG, strlen(MSG), 0, res->ai_addr, res->ai_addrlen);
if (locNumByteSend == -1)
{
printf("Error send to: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 3;
}
printf("Client: sent %d bytes to %s:%s\n", locNumByteSend, SERVERIP, SERVERPORT);
// Receive message from server.
char buf[MAXBUFLEN];
struct sockaddr_storage their_addr;
socklen_t addr_len = sizeof their_addr;
int locNumByteRecv = recvfrom(locInitSocket, buf, MAXBUFLEN, 0, (struct sockaddr *)&their_addr, &addr_len);
if (locNumByteRecv == -1)
{
printf("Error receive from: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 4;
}
// -----------------------------------------
char s[INET6_ADDRSTRLEN];
printf("Client: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
printf("Client: packet is %d bytes long\n", locNumByteRecv);
buf[locNumByteRecv] = '[=11=]';
printf("Client: packet contains \"%s\"\n", buf);
// -----------------------------------------
// Free the linked-list.
freeaddrinfo(res);
// Close the socket.
close(locInitSocket);
printf("Socket closed.\nHave a nice day :)\n");
return 0;
}
这是我的 C# 代码不起作用:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
server.Close();
Console.WriteLine("Welcome send");
// End This work fine ----------------------------
IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint ServerEndPoint = new IPEndPoint(IPAddress.Any, 8642);
Socket WinSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
WinSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 8642);
EndPoint Remote = (EndPoint)(sender);
WinSocket.Bind(ServerEndPoint);
data = new byte[256];
int recv = WinSocket.ReceiveFrom(data, ref Remote);
WinSocket.Close();
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
这是另一个不起作用的 C# 代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
server.Close();
Console.WriteLine("Welcome send");
// End This work fine ----------------------------
UdpClient listener = new UdpClient(8642);
listener.Client.ReceiveTimeout = 5000;
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 8642);
byte[] receivebytes;
receivebytes = listener.Receive(ref endpoint);
Console.WriteLine(Encoding.ASCII.GetString(receivebytes, 0, receivebytes.Length));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
谢谢@Peter!
在我检查我的代码后,这里是解决方案:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
Console.WriteLine("Welcome send");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
data = new byte[256];
int recv = server.ReceiveFrom(data, ref Remote);
server.Close();
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
我无法从 UDP 套接字接收消息。 我制作了运行良好的 C++ 服务器和客户端应用程序。服务器从客户端接收消息然后发回响应,客户端接收消息然后他们都关闭套接字并退出。现在我尝试用 C# 创建客户端程序,但我无法从服务器接收消息。客户端 C# 应用程序发送消息,然后 C++ 服务器正确接收它,但是当服务器发回他的响应时,客户端无法接收它。我已经在本地虚拟机和 VPS 上测试了我的服务器,结果是一样的。有什么想法吗?
服务器代码 C++:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <pthread.h>
#define MSG "Hi i'm server"
#define SERVERPORT "8642"
#define MAXBUFLEN 100
// Get sockaddr, IPv4 or IPv6.
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int LoginUser()
{
int locUserId = 0;
// Call DB.
return 0;
}
int main(int argc, char *argv[])
{
// Load up address structs.
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // Use IPv4 or IPv6, whichever.
hints.ai_socktype = SOCK_DGRAM; // UDP.
hints.ai_flags = AI_PASSIVE; // Fill in my IP for me.
int locInitAddrInfo = getaddrinfo(NULL, SERVERPORT, &hints, &res);
if (locInitAddrInfo != 0)
{
printf("Error initialize address info: %s\n", gai_strerror(locInitAddrInfo));
return 1;
}
printf("Address info initialized: %i\n", locInitAddrInfo);
// Initialize the socket.
int locInitSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (locInitSocket == -1)
{
printf("Error initialize socket: %s\n", strerror(errno));
freeaddrinfo(res);
return 2;
}
printf("Socket initialized: %i\n", locInitSocket);
// Bind a name to a socket.
int locInitBind = bind(locInitSocket, res->ai_addr, res->ai_addrlen);
if (locInitBind == -1)
{
printf("Error bind socket: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 3;
}
printf("Socket binded: %i\n", locInitBind);
// Receive message from client.
char buf[MAXBUFLEN];
struct sockaddr_storage their_addr;
socklen_t addr_len = sizeof their_addr;
int locNumByteRecv = recvfrom(locInitSocket, buf, MAXBUFLEN, 0, (struct sockaddr *)&their_addr, &addr_len);
if (locNumByteRecv == -1)
{
printf("Error receive from: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 4;
}
// -----------------------------------------
char s[INET6_ADDRSTRLEN];
printf("Server: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
printf("Server: packet is %d bytes long\n", locNumByteRecv);
buf[locNumByteRecv] = '[=10=]';
printf("Server: packet contains \"%s\"\n", buf);
// -----------------------------------------
sleep(2);
// Send to client.
int locNumByteSend = sendto(locInitSocket, MSG, strlen(MSG), 0, (struct sockaddr *)&their_addr, addr_len);
if (locNumByteSend == -1)
{
printf("Error send to: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 5;
}
printf("Server: sent %d bytes to %s:%s\n", locNumByteSend, inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s), SERVERPORT);
// Free the linked-list.
freeaddrinfo(res);
// Close the socket.
close(locInitSocket);
printf("Socket closed.\nHave a nice day :)\n");
return 0;
}
客户端代码 C++:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MSG "Hi i'm client"
#define SERVERIP "192.168.1.33"
#define SERVERPORT "8642"
#define MAXBUFLEN 100
// Get sockaddr, IPv4 or IPv6.
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int argc, char *argv[])
{
// Load up address structs.
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // Use IPv4 or IPv6, whichever.
hints.ai_socktype = SOCK_DGRAM; // UDP.
int locInitAddrInfo = getaddrinfo(SERVERIP, SERVERPORT, &hints, &res);
if (locInitAddrInfo != 0)
{
printf("Error initialize address info: %s\n", gai_strerror(locInitAddrInfo));
return 1;
}
printf("Address info initialized: %i\n", locInitAddrInfo);
// Initialize the socket.
int locInitSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (locInitSocket == -1)
{
printf("Error initialize socket: %s\n", strerror(errno));
freeaddrinfo(res);
return 2;
}
printf("Socket initialized: %i\n", locInitSocket);
// Send to server.
int locNumByteSend = sendto(locInitSocket, MSG, strlen(MSG), 0, res->ai_addr, res->ai_addrlen);
if (locNumByteSend == -1)
{
printf("Error send to: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 3;
}
printf("Client: sent %d bytes to %s:%s\n", locNumByteSend, SERVERIP, SERVERPORT);
// Receive message from server.
char buf[MAXBUFLEN];
struct sockaddr_storage their_addr;
socklen_t addr_len = sizeof their_addr;
int locNumByteRecv = recvfrom(locInitSocket, buf, MAXBUFLEN, 0, (struct sockaddr *)&their_addr, &addr_len);
if (locNumByteRecv == -1)
{
printf("Error receive from: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 4;
}
// -----------------------------------------
char s[INET6_ADDRSTRLEN];
printf("Client: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
printf("Client: packet is %d bytes long\n", locNumByteRecv);
buf[locNumByteRecv] = '[=11=]';
printf("Client: packet contains \"%s\"\n", buf);
// -----------------------------------------
// Free the linked-list.
freeaddrinfo(res);
// Close the socket.
close(locInitSocket);
printf("Socket closed.\nHave a nice day :)\n");
return 0;
}
这是我的 C# 代码不起作用:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
server.Close();
Console.WriteLine("Welcome send");
// End This work fine ----------------------------
IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint ServerEndPoint = new IPEndPoint(IPAddress.Any, 8642);
Socket WinSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
WinSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 8642);
EndPoint Remote = (EndPoint)(sender);
WinSocket.Bind(ServerEndPoint);
data = new byte[256];
int recv = WinSocket.ReceiveFrom(data, ref Remote);
WinSocket.Close();
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
这是另一个不起作用的 C# 代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
server.Close();
Console.WriteLine("Welcome send");
// End This work fine ----------------------------
UdpClient listener = new UdpClient(8642);
listener.Client.ReceiveTimeout = 5000;
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 8642);
byte[] receivebytes;
receivebytes = listener.Receive(ref endpoint);
Console.WriteLine(Encoding.ASCII.GetString(receivebytes, 0, receivebytes.Length));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
谢谢@Peter! 在我检查我的代码后,这里是解决方案:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
Console.WriteLine("Welcome send");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
data = new byte[256];
int recv = server.ReceiveFrom(data, ref Remote);
server.Close();
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}