C++ UDP客户端/套接字编程:不能发送和接收
Posted
技术标签:
【中文标题】C++ UDP客户端/套接字编程:不能发送和接收【英文标题】:C++ UDP Client/Socket Programming: can't send and receive 【发布时间】:2015-11-29 01:44:36 【问题描述】:第一次来。我正在尝试实现一个 UDP Socket 客户端/服务器来与 BGI 一起为我的大学考试。我想发送移动坐标并接收测试字符。但是当我使用 recvfrom() 时它不起作用,没有它就可以正常工作。对不起我的英语。
这是客户端文件:
#define WIN32_LEAN_AND_MEAN
#include<winsock2.h>
#include<windows.h>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<graphics.h>
#define SIZE 512
#define PORT 20252
#define SERVER_IP "127.0.0.1"
#define CLIENT_IP "127.0.0.1"
using namespace std;
int main()
WSADATA wsaData;
SOCKET ClientSocket;
int server_length;
struct sockaddr_in server;
struct sockaddr_in client;
char print_buffer[SIZE];
/* ==================================================================================*/
WSAStartup(0x0101, &wsaData);
ClientSocket = socket(AF_INET, SOCK_DGRAM, 0);
memset((void *)&server, '\0', sizeof(struct sockaddr_in));
memset((void *)&client, '\0', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = inet_addr(SERVER_IP);
client.sin_family = AF_INET;
client.sin_port = htons(PORT);
client.sin_addr.s_addr = inet_addr(CLIENT_IP);
bind(ClientSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in));
/* ==================================================================================*/
int x = 0;
while (x != 1)
server_length = sizeof(struct sockaddr_in);
if (GetKeyState(VK_RIGHT)&0x80)
char send_right_P1[SIZE] = "P1RIGHT\r\n";
sendto(ClientSocket, send_right_P1, (int)strlen(send_right_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_right_P1[0], 0, sizeof(send_right_P1));
if (GetKeyState(VK_LEFT)&0x80)
char send_left_P1[SIZE] = "P1LEFT\r\n";
sendto(ClientSocket, send_left_P1, (int)strlen(send_left_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_left_P1[0], 0, sizeof(send_left_P1));
if (GetKeyState(VK_UP)&0x80)
char send_up_P1[SIZE] = "P1UP\r\n";
sendto(ClientSocket, send_up_P1, (int)strlen(send_up_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_up_P1[0], 0, sizeof(send_up_P1));
if (GetKeyState(VK_DOWN)&0x80)
char send_down_P1[SIZE] = "P1DOWN\r\n";
sendto(ClientSocket, send_down_P1, (int)strlen(send_down_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_down_P1[0], 0, sizeof(send_down_P1));
if (GetKeyState(VK_ESCAPE)&0x80)
char send_escape[SIZE] = "ESCAPE\r\n";
sendto(ClientSocket, send_escape, (int)strlen(send_escape) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_escape[0], 0, sizeof(send_escape));
recvfrom(ClientSocket, print_buffer, SIZE, 0, (struct sockaddr *)&server, &server_length);
if (strcmp(print_buffer, "TESTE\r\n" ) == 0)
cout << print_buffer;
else cout << "Failed\n";
memset(&print_buffer[0], 0, sizeof(print_buffer));
delay(50);
closesocket(ClientSocket);
WSACleanup();
return 0;
这是服务器:
#define WIN32_LEAN_AND_MEAN
#include<winsock2.h>
#include<windows.h>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<graphics.h>
#include "images.h"
#define SIZE 512
#define PORT 20252
#define SERVER_IP "127.0.0.1"
#define CLIENT_IP "127.0.0.1"
using namespace std;
int main()
WSADATA wsaData;
SOCKET ServerSocket;
int client_length;
struct sockaddr_in server;
struct sockaddr_in client;
char Player1_Buffer[SIZE];
/* ==================================================================================*/
initwindow(800, 600);
int pg = 2, passo = 5, fim = 0;
GetImages();
int Pos1X = 200, Pos1Y = 300, direction1 = 1;
int Pos2X = 600, Pos2Y = 300, direction2 = 1;
/* ==================================================================================*/
WSAStartup(0x0101, &wsaData);
ServerSocket = socket(AF_INET, SOCK_DGRAM, 0);
memset((void *)&server, '\0', sizeof(struct sockaddr_in));
memset((void *)&client, '\0', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = inet_addr(SERVER_IP);
client.sin_family = AF_INET;
client.sin_port = htons(PORT);
client.sin_addr.s_addr = inet_addr(CLIENT_IP);
bind(ServerSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
printf("Server running on %u.%u.%u.%u\n", (unsigned char)server.sin_addr.S_un.S_un_b.s_b1,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b2,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b3,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b4);
printf("Press CTRL + C to quit\n");
while (fim != 1)
if (pg == 1) pg = 2; else pg = 1;
setactivepage(pg);
cleardevice();
putimage(0, 0, background, OR_PUT);
drawBoy(Pos1X, Pos1Y, direction1);
setvisualpage(pg);
delay(50);
client_length = (int)sizeof(struct sockaddr_in);
recvfrom(ServerSocket, Player1_Buffer, SIZE, 0, (struct sockaddr *)&client, &client_length);
if (strcmp(Player1_Buffer, "P1RIGHT\r\n") == 0)
Pos1X = Pos1X + passo;
direction1 = 3;
cout << "Received from Player1: " << Player1_Buffer << endl;
if (strcmp(Player1_Buffer, "P1LEFT\r\n" ) == 0)
Pos1X = Pos1X - passo;
direction1 = 4;
cout << "Received from Player1: " << Player1_Buffer << endl;
if (strcmp(Player1_Buffer, "P1UP\r\n" ) == 0)
Pos1Y = Pos1Y - passo;
direction1 = 2;
cout << "Received from Player1: " << Player1_Buffer << endl;
if (strcmp(Player1_Buffer, "P1DOWN\r\n" ) == 0)
Pos1Y = Pos1Y + passo;
direction1 = 1;
cout << "Received from Player1: " << Player1_Buffer << endl;
char print_buffer[SIZE] = "TESTE\r\n";
sendto(ServerSocket, print_buffer, (int)strlen(print_buffer) + 1, 0, (struct sockaddr *)&client, client_length);
if (strcmp(Player1_Buffer, "ESCAPE\r\n") == 0)
fim = 1;
cout << "Received from Player1: " << Player1_Buffer << endl;
closesocket(ServerSocket);
WSACleanup();
return 0;
【问题讨论】:
尽量放最短的产生错误的源代码 【参考方案1】:不要bind()
客户端上的套接字。您将客户端套接字绑定到 127.0.0.1:20252,然后将数据发送到相同的地址:端口对。
只需删除客户端代码中对bind()
的调用即可。
另一个选项(也在客户端上)是绑定到端口 0,这将分配一个未使用的端口。
另外:检查bind()
、sendto()
、recvfrom()
等的返回值,如果失败则显示错误代码。
还有一个:recvfrom()
的长度参数必须在调用前初始化。例如,在客户端你应该这样做:
server_length = sizeof(server);
recvfrom(ClientSocket, print_buffer, SIZE, 0, (struct sockaddr *)&server, &server_length);
在服务器端也是如此。
【讨论】:
以上是关于C++ UDP客户端/套接字编程:不能发送和接收的主要内容,如果未能解决你的问题,请参考以下文章