2014-04-30 122 views
0

我正在尝试使用UDP编写简单的客户端和服务器。我可以发送数据从客户端到服务器,并且服务器接收它,但是当我从服务器发送数据到客户端时,它根本不工作... (它不检测任何东西,并粘贴在recvfrom功能..正在编写客户端和服务器UDP UDP

这里是我的服务器代码:

SOCKET ServerOn() 
{ 
SOCKET ListenSocket; 
WSADATA wsaData; 
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 
if (iResult != NO_ERROR) 
{ 
    exit(0); 
} 

// Create a SOCKET for listening for 
// incoming connection requests. 
ListenSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
if (ListenSocket == INVALID_SOCKET) 
{ 
    WSACleanup(); 
    exit(1); 
} 

// The sockaddr_in structure specifies the address family, 
// IP address, and port for the socket that is being bound. 
sockaddr_in service; 
service.sin_family = AF_INET; 
service.sin_addr.s_addr = inet_addr("0.0.0.0"); 
service.sin_port = htons(2583); 

if (bind(ListenSocket,(SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR) 
{ 
    closesocket(ListenSocket); 
    WSACleanup(); 
    exit(2); 
} 

return ListenSocket; 
} 

在这个函数中,我初始化端口服务器2583

这是我在其他代码服务器:

int size = sizeof(service); 
char *data = new char[500]; 

recvfrom(s,data, 500, NULL, (SOCKADDR*)&service, &size); // Getting a new connection 

    sockaddr_in service; 
service.sin_family = AF_INET; 
service.sin_addr.s_addr = inet_addr("10.0.0.1"); 
service.sin_port = htons(2583); 

    int addrSize = sizeof(service); 
if (sendto(s, "123", 3, NULL, (struct sockaddr*)&service, addrSize) != 3) 
    printf("%d", WSAGetLastError()); // Print error if did not send successfully 

“10.0.0.1”是客户端的IP(我确信它是)...... 我没有找到一种方法,从插座获取IP全自动,所以我只是把它马上现在...

这里是我的客户端代码:

SOCKET ConnectToServer() 
{ 
//---------------------- 
// Initialize Winsock 
WSADATA wsaData; 
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 
if (iResult != NO_ERROR) 
{ 
    return NULL; 
} 
//---------------------- 
// Create a SOCKET for connecting to server 
SOCKET ConnectSocket; 
ConnectSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 

if (ConnectSocket == INVALID_SOCKET) 
{ 
    WSACleanup(); 
    return NULL; 
} 
//---------------------- 
// The sockaddr_in structure specifies the address family, 
// IP address, and port of the server to be connected to. 
sockaddr_in clientService; 
clientService.sin_family = AF_INET; 
clientService.sin_addr.s_addr = inet_addr(Default_IP.c_str()); // IP 
clientService.sin_port = htons(Default_Port); // Port 

//---------------------- 
// Connect to server. 
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService)); // Connecting 
while (iResult == SOCKET_ERROR) // ERROR, could not connect. keep trying 
{ 
    iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService)); // Connecting 
} 

    return ConnectSocket; 
    } 

在这段代码中,我连接到客户。

这里是客户端代码的其余部分:

sockaddr_in service; 
service.sin_family = AF_INET; 
service.sin_addr.s_addr = inet_addr("10.0.0.1"); 
service.sin_port = htons(2583); 
s = ConnectToServer(); 
sendto(s, "123", 3, NULL, (struct sockaddr*)&service, addrSize); 

while(true) 
{ 
    result = recvfrom(s, (char*)waveIn, NUMPTS * sizeof(short int), NULL, (struct sockaddr *)&service, &addrSize); 

    if (result > 0) 
    { 
     std::cout << "New Data!" << std::endl; 
    } 
    else 
     printf("%d\n", WSAGetLastError()); 
} 

在客户端的sendto功能不工作,而服务器临危它,但在服务器尝试将数据发送回客户端,它什么也收不到,它卡在recvfrom功能上。

我在做什么错?我从同一台计算机上运行客户端和服务器,这意味着它们都具有相同的IP地址(“10.0.0.1”),但它在使用带有TCP的套接字时总是适用于我,所以我'我也在这里做过。

虽然,我也尝试使用此代码与2台不同的电脑,我仍然有同样的错误......

谢谢!

+0

UDP无连接 - 您不应尝试连接到服务器端口。 –

+0

@MartinJames你是什么意思?在客户端中,更改端口?它会如何改变我的错误,客户没有收到任何东西? – Amit

+0

@MartinJames:UDP可能是无连接的,但在UDP套接字上调用'connect()'是有效的。它只是建立本地和远程IP端口对之间的本地静态关联,从而允许使用send()和recv()与sento()和recvfrom(),以及错误报告如果接收方向发送方发送ICMP差错数据包(在没有connect()的情况下会被忽略)。 –

回答

1

当服务器调用recvfrom()时,它会报告数据来自的IP:端口。您需要将您的回复发送回相同的IP:端口,例如:

sockaddr_in service; 
int size = sizeof(service); 
char data[500]; 

int len = recvfrom(s, data, 500, NULL, (SOCKADDR*)&service, &size); 
if (len == -1) 
    printf("recv failed: %d", WSAGetLastError()); // Print error if did not recv successfully 
else 
{ 
    if (sendto(s, "123", 3, NULL, (struct sockaddr*)&service, size) == -1) 
     printf("send failed: %d", WSAGetLastError()); // Print error if did not send successfully 
} 
+0

它的工作!非常感谢!! 问题是,我在'recvfrom'中创建了一个新的'sockaddr_in',并在'sendfrom'中创建了一个新的错误! 一个问题: 如果我想使用多线程,就像每个新连接都有一个新线程,是否需要将'sockaddr'传递给线程,并初始化一个新的'sockaddr'来接收新线程连接,并在所有线程中使用相同的套接字?或者我需要为每个连接一个新的套接字?我希望我很清楚! 再次感谢! – Amit

+0

UDP中没有连接。您可以重新使用原始套接字,或创建一个新的套接字,UDP不关心(TCP关心)。至于'sockaddr',你可以在堆栈上分配它(如我所示)并将它的副本传递给每个线程,或者你可以每次动态分配一个新的'sockaddr'并让一个线程获得它的所有权。这真的不要紧。重要的是'sockaddr'的*内容*,而不是如何管理内存。只要你将一个*等价的*'sockaddr'传递给'sendto()',它表示''recvfrom()'报告的相同的IP:端口,你就没事了。 –