C语言中TCP套接字连接错误

问题描述 投票:0回答:1

我已经发布了有关此问题的问题,但我没有找到任何答案,而且该帖子现已关闭,我不知道为什么?不过,我重新发布了这个问题。

我想在一个简单的客户端-服务器架构中连接两个 TCP 套接字,并且我设置了两个虚拟机来模拟两台想要通信的机器。

这里是客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>

int main(int argc, char ** argv) {
    //controllo che la porta venga indicata in riga di comando
    if (argc != 2) {
        printf("Usage: %s <port>", argv[0]);
        exit(0);
    }
    //variabili di controllo, socket e indirizzo
    int port = atoi(argv[1]);
    int sock;
    struct sockaddr_in addr;
    socklen_t addr_size;
    char buffer[1024];
    int n;
    //chiamata a socket e subito dopo controllo
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("[-] Error while creating socket.\n");
        exit(1);
    }

    printf("[+] TCP socket created. \n");
    memset(&addr, '\0', sizeof(addr));//setto i byte a 0
    //imposto gli attributi dell'indirizzo
    addr.sin_family = PF_INET;
    addr.sin_port = port;
    addr.sin_addr.s_addr = INADDR_ANY;
    //connetto la socket
    n = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
    if (n < 0) {
        printf("Error while connecting the socket...: %s\n", strerror(errno));
    printf("Errno value = %d", errno);
        exit(1);
    }
    printf("[+] Client connected.\n");

    bzero(buffer, 1024);// azzero i byte del buffer
    strcpy(buffer, "Hello World");
    printf("Client: %s\n", buffer);
    send(sock, buffer, strlen(buffer), 0); // mando il messaggio contenuto nel buffer

    bzero(buffer, 1024);
    recv(sock, buffer, sizeof(buffer), 0); //ricevo la risposta del server 
    printf("Server: %s\n", buffer);

    close(sock); // chiudo la connessione lato client
    printf("[+] Disconnected from the server");

    return 0;
} 

这是服务器代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(int argc, char** argv) {
    //controllo che da riga di comando venga inserita la porta a cui collegare la socket
    if (argc != 2) {
        printf("Usage: %s <port>", argv[0]);
        exit(0);
    }
    //creo tutte le variabili che mi serviranno 
    int port = atoi(argv[1]); //porta presa da riga di comando
    int server_sock, client_sock; //socket per server e client 
    struct sockaddr_in server_addr, client_addr; //struct per gestire gli indirizzi di server e client(IPv4, IPv6)
    socklen_t addr_size;    //lunghezza degli indirizzi
    char buffer[1024];  //buffer per il trasferimento dei messaggi
    int n;  //variabile di controllo

    //chiamata alla funzione socket che restituisce un valore int a server_sock
    server_sock = socket(AF_INET, SOCK_STREAM, 0); 
    //controllo che la chiamata socket() abbia restituito un valore > 0, quindi esito della chiamata positivo
    if (server_sock < 0) {
        perror("[-] Error while creating socket.\n");
        exit(1);
    }

    printf("[+] TCP socket created. \n");
    //setto i byte della memoria a 0
    memset(&server_addr, '\0', sizeof(server_addr));
    //assegno i vari attributi dell'indirizzo
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = port;
    server_addr.sin_addr.s_addr = INADDR_ANY;

    //chiamata alla funzione bind che associa la socket con la porta e ne metto il valore di ritorno in n 
    n = bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
    //controllo che la chiamata precedente sia andata bene quindi n > 0
    if (n < 0) {
        perror("[-] Error while binding the socket.\n");
        exit(1);
    }
    printf("[+] Socket binded to the port %d\n", port);

    //metto in ascolto il server
    int listenVar = 0;
    listenVar = listen(server_sock, 5);
    if (listenVar < 0) {
        perror("[-] Error while setup listening phase...\n");
        exit(1);
    }
    printf("[+] Listening...\n");

    //ciclo su i client che si collegano al server
    while(1) {
        
        addr_size = sizeof(client_addr); // size dell'indirizzo del client
        //chiamata alla funzione accept, che restituisce un valore int 
        client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &addr_size);
        if (client_sock < 0) {
            perror("[-]Error while accepting the connection");
            exit(1);
        }
        char ipString[40]; // stringa per salvare l'ip del client che si è collegato al server
        inet_ntop(AF_INET, &client_addr, ipString, sizeof(client_addr)); //converto l'ip in un formato di testo
        printf("[+] Client connected.\n Client IP:%s\n", ipString); //stampo l'indirizzo che si è collegato al server

        bzero(buffer, 1024); //azzero i byte del buffer
        recv(client_sock, buffer, sizeof(buffer), 0); //ricevo il messaggio dal client
        printf("Client: %s\n", buffer); // stampo il messaggio salvato in buffer

        bzero(buffer,1024); //riazzero il buffer 
        strcpy(buffer, "Hi from the server"); // passo una stringa nel buffer
        printf("Server: %s\n", buffer); 
        send(client_sock, buffer, strlen(buffer), 0); // mando il messaggio del buffer al client

        close(client_sock); //chiudo la connessione 
        printf("[+] Client disconnected.\n");
    }

    return 0;
}

我的功能控制有问题,

errno
返回值111,或者连接被拒绝,但我不明白为什么。我认为不存在连接设置问题,因为如果我在机器上执行
nc
命令,它们都可以正常通信。

c sockets tcp
1个回答
0
投票

在客户端,

INADDR_ANY
(0.0.0.0) 不是
connect()
的有效 IP 地址。在服务器端,您可以
bind()
INADDR_ANY
的服务器套接字来侦听所有本地网络接口。

调用时需要指定服务器的实际IP地址

connect()
。由于您的客户端和服务器在单独的虚拟机中运行,因此服务器虚拟机需要分配一个可从客户端虚拟机访问的公共 IP 地址。

此外,在为

htons()
字段赋值时需要使用
sinaddr_in::sin_port

© www.soinside.com 2019 - 2024. All rights reserved.