简体   繁体   中英

C++ UDP Client/Socket Programming: can't send and receive

First time here. I'm trying to implement an UDP Socket client/server to work with BGI for my college exam. I want to send the move coordinates and receive a test char. But when I use recvfrom() it doesn't work, without it works fine. Sorry about my english.

Here's the client file:

#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;
}

Here's the server:

#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;
}

Don't bind() the socket on the client. You're binding the client socket to 127.0.0.1:20252, then sending data to the same address:port pair.

Just remove the call to bind() in the client code.

Another option (also on the client) is to bind to port 0, which will assign an unused port.

Also: Check the return values from bind() , sendto() , recvfrom() , etc and display the error code if they fail.

One more: The length parameter to recvfrom() must be initialized before the call. For example, in the client you should do this:

server_length = sizeof(server);
recvfrom(ClientSocket, print_buffer, SIZE, 0, (struct sockaddr *)&server, &server_length);

Likewise on the server side.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM