С++ UDP Client/Socket Programming: невозможно отправлять и получать

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

person dirceu86    schedule 29.11.2015    source источник
comment
Попробуйте поставить кратчайший исходный код, выдающий ошибку   -  person Roberto    schedule 29.11.2015


Ответы (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);

Так же и на стороне сервера.

person keithmo    schedule 29.11.2015