Программирование клиента / сокета на C ++ UDP: невозможно отправить и получить

Впервые здесь. Я пытаюсь реализовать клиент / сервер 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);

Аналогично на стороне сервера.

0

Другие решения

Других решений пока нет …