Rablidad
Rablidad

Reputation: 55

Cant compile Windows Socket in C

i've made in my windows desktop, a c socket code, but when i compile, it gives me erros, i dnt know how to proceed, can someone help me? i am working in windows 7, but also tried this same code in windows 10, but i got the same errors, here is the c code, i also tried in c++ but got the same errors, c code below:

#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();


}

error:

gcc -o csocketcode csocketcode.c -lwinsock2

Upvotes: 0

Views: 1025

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 598114

When calling send() and recv(), DON'T use the & operator to pass your char[] arrays. Arrays decay into pointers, so pass the arrays as-is. send() expects a const char*, and recv() expects a char*, but you are passing them both a char(*)[4096] instead, which is not what the functions want. Let the arrays decay to char* for you.

There are other problems with your code:

  • missing #include <windows.h>

  • sockfd is declared as int when it should be SOCKET instead.

  • gets() is dangerous. Also, you are (potentially) sending more data than gets() actually returns.

  • your use of printf() is expecting null-terminated data, but recv() does not guarantee a null terminator.

  • no error handling at all.

Try this instead:

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

Upvotes: 2

rafix07
rafix07

Reputation: 20969

Your code under gcc compiles but cannot be linked because gcc doesn't recognize

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

Add -Werror=unknown-pragmas as compiler flag and you will see error: ignoring pragma comment as compiler message.

So you need to pass Ws2_32 library to link in command line:

gcc -o csocketcode csocketcode.c -lWs2_32

gcc tells you about incompatible pointers type (it is treated as warnings), what is described in Chipster's answer. Fix it.

Upvotes: 0

Related Questions