0

第一次来这里。我正在尝试实现一个 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;
}
4

1 回答 1

0

不要bind()在客户端上的套接字。您将客户端套接字绑定到 127.0.0.1:20252,然后将数据发送到相同的地址:端口对。

只需删除客户端代码中的调用即可bind()

另一个选项(也在客户端上)是绑定到端口 0,这将分配一个未使用的端口。

另外:检查, , 等的返回值bind(),如果失败则显示错误代码。sendto()recvfrom()

recvfrom()再一:必须在调用前初始化长度参数to 。例如,在客户端中,您应该这样做:

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

在服务器端也是如此。

于 2015-11-29T01:49:21.057 回答