Не могу скомпилировать Windows Socket в C - PullRequest
0 голосов
/ 31 января 2019

Я сделал на своем рабочем столе Windows код сокета переменного тока, но когда я компилирую, это дает мне ошибки, я не знаю, как поступить, кто-то может мне помочь?Я работаю в Windows 7, но также попробовал этот же код в Windows 10, но я получил те же ошибки, вот код C, я также пытался в C ++, но получил те же ошибки, код C ниже:

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string.h>
#pragma comment (lib, "Ws2_32.lib")

#define PORT 5555
#define HOST "192.168.1.30"
#define MAX_L 4096
int main(void){
    char bfs[MAX_L], bfr[MAX_L];
    int sockfd;
    socklen_t sin_size = sizeof(struct sockaddr_in);
    struct sockaddr_in target_addr;
    struct WSAData wsa;
    WSAStartup(MAKEWORD(2,2),&wsa);

    sockfd = socket(PF_INET, SOCK_STREAM, 0);

    target_addr.sin_port = htons(PORT);
    target_addr.sin_family = AF_INET;
    target_addr.sin_addr.s_addr = inet_addr(HOST);

    connect(sockfd, (struct sockaddr *)&target_addr, sin_size);

    while(1){

        gets(bfs);
        send(sockfd, &bfs, MAX_L, 0);
        recv(sockfd, &bfr, MAX_L, 0);
        printf("%s\n", bfr);


    }

    closesocket((SOCKET) sockfd);

    WSACleanup();


}

ошибка:

gcc -o csocketcode csocketcode.c -lwinsock2

Ответы [ 2 ]

0 голосов
/ 31 января 2019

При вызове send() и recv() НЕ используйте оператор & для передачи ваших char[] массивов.Массивы распадаются на указатели, поэтому передайте массивы как есть.send() ожидает const char*, а recv() ожидает char*, но вместо этого вы передаете им оба char(*)[4096], а это не то, чего хотят функции.Пусть массивы для вас уменьшатся до char*.

Есть другие проблемы с вашим кодом:

  • отсутствует #include <windows.h>

  • sockfd объявляется как int, когда вместо него должно быть SOCKET.

  • gets() опасно .Кроме того, вы (потенциально) отправляете больше данных, чем на самом деле возвращает gets().

  • при использовании printf() ожидаются данные с нулевым символом в конце, но recv() не гарантирует нулевого терминатора.

  • без ошибокобработка вообще.

Попробуйте вместо этого:

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <string.h>

#pragma comment (lib, "Ws2_32.lib")

#define PORT 5555
#define HOST "192.168.1.30"
#define MAX_L 4096

int main(void) {
    char bfs[MAX_L], bfr[MAX_L];
    SOCKET sockfd;
    struct sockaddr_in target_addr;
    struct WSAData wsa;
    int err, num_recvd;
    size_t str_len;

    err = WSAStartup(MAKEWORD(2,2), &wsa);
    if (err != 0) {
        fprintf(stderr, "WSAStartup() failed, error %d\n", err);
        return -1;
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == INVALID_SOCKET) {
        err = WSAGetLastError();
        fprintf(stderr, "socket() failed, error %d\n", err);
        WSACleanup();
        return -1;
    }

    target_addr.sin_port = htons(PORT);
    target_addr.sin_family = AF_INET;
    target_addr.sin_addr.s_addr = inet_addr(HOST);

    if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(target_addr)) == SOCKET_ERROR) {
        err = WSAGetLastError();
        fprintf(stderr, "connect() failed, error %d\n", err);
        closesocket(sockfd);
        WSACleanup();
        return -1;
    }

    while (fgets(bfs, MAX_L, stdin)) {
        str_len = strlen(bfs);
        if ((str_len > 0) && (bfs[str_len-1] == '\n')) {
            --str_len;
        }

        if (send(sockfd, bfs, str_len, 0) == SOCKET_ERROR) {
            err = WSAGetLastError();
            fprintf(stderr, "send() failed, error %d\n", err);
            closesocket(sockfd);
            WSACleanup();
            return -1;
        }

        num_recvd = recv(sockfd, bfr, MAX_L, 0);
        if (num_recvd == SOCKET_ERROR) {
            err = WSAGetLastError();
            fprintf(stderr, "recv() failed, error %d\n", err);
            closesocket(sockfd);
            WSACleanup();
            return -1;
        }

        if (num_recvd == 0) {
            break;
        }

        printf("%.*s\n", num_recvd, bfr);
    }

    closesocket(sockfd);
    WSACleanup();

    return 0;
}
0 голосов
/ 31 января 2019

Ваш код в gcc компилируется, но не может быть связан, потому что gcc не распознает

#pragma comment (lib, "Ws2_32.lib")

Добавьте -Werror=unknown-pragmas как флаг компилятора, и вы увидите error: ignoring pragma comment каксообщение компилятора.

Таким образом, вам нужно передать библиотеку Ws2_32 для ссылки в командной строке:

gcc -o csocketcode csocketcode.c -lWs2_32

gcc сообщает вам о несовместимых типах указателей (это рассматривается как предупреждение),что описано в ответе Чипстера.Исправь это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...