第一次来这里。我正在尝试实现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;
}
答案 0 :(得分:0)
不要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);
同样在服务器端。