TCP Client-Server “bad address” error (in C)

試著忘記壹切 提交于 2020-01-03 01:42:09

问题


Although it seems to be correctly implemented, it keeps on returning me ERROR when I establish a connection using the loopback address(127.0.0.1).

In addition to a simple TCP Client/Server connection, I have added an additional case:

If the client tries to send data but finds the connection closed, it is closed too. I perform it by checking if received data is equal to 0 (recv).

Given error:

CLIENT:
Welcome to the Client mode
Please, enter the Server's IP Address and Port (eg. 192.128.192.0 1320) 
127.0.0.1 2700
Connected to the server. Now you can send messages
Please, enter a message. Enter "FINISH" if you want to finish the connection
ECHO 
client: connection closed ->: Success
 (1 bytes)Closing the connection 

SERVER:
Hello and welcome to the Server mode
Please, enter the Server's Port (eg. 1320) 
2700
Server socket successfully configured
Server listening [Clients allowed: 5]
server: accept error: Bad address

Client implementation:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <netinet/in.h>
#include <netinet/ip.h>

/**

 struct sockaddr{
     uint8_t sa_len; // struct length
     sa_family_t sa_family; //protocol family: AF_XXX
     char sa_data[8]; //socket addr
 }

 */

//void notConnected();
int main(){

    struct sockaddr_in  serv_addr;  //port + ip_addr
    int                 my_socket, tcp_port;
    char                serv_host_addr[30];

    char                buffer[1024], inbuff[1024];
    int                 io_buffer;

    printf("Welcome to the Client mode\n");

    //CONFIGURING THE CONNECTION
    my_socket = socket(AF_INET, SOCK_STREAM, 0);//(2)
    if(my_socket < 0){
        perror("client: socket() error ->");
        exit(EXIT_FAILURE);
    }

    bzero(&serv_addr, sizeof(serv_addr));//(4)
    printf("Please, enter the Server's IP Address and Port (eg. 192.128.192.0 1320) \n");
    scanf("%s %d", serv_host_addr, &tcp_port);//(1)


    serv_addr.sin_family = AF_INET ;
    serv_addr.sin_port = htons(tcp_port);
    if(inet_pton(AF_INET,serv_host_addr,&serv_addr.sin_addr) < 1){
        perror("client: inet_pton() error ->");
        exit(EXIT_FAILURE);
    }

    if((connect(my_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr) )) < 0)//(5)
    {
        perror("client: connect() error ->");
        exit(EXIT_FAILURE);
    }


    //ONCE CONNECTED, START THE SENDING/RECEIVING
    printf("Connected to the server. Now you can send messages\n");
    bzero(&buffer, sizeof(buffer));

    while(strcmp(buffer, "OK\n") != 0){

        printf("Please, enter a message. Enter \"FINISH\" if you want to finish the connection\n");//(3)
        bzero(&buffer, sizeof(buffer));
        fgets(buffer, sizeof(buffer), stdin);

        io_buffer = send(my_socket, buffer, strlen(buffer),0);//(6)
        if(io_buffer < 0){
            perror("client: send() error ->");
            exit(EXIT_FAILURE);
        }
        printf("ECHO %s (%d bytes)", buffer, io_buffer);


        //RECEIVE AND CHECK IF CONNECTION HAS BEEN CLOSED
        io_buffer = recv(my_socket, buffer, sizeof(buffer),0);
        if(io_buffer < 0){
            perror("client: recv() error ->");
            exit(EXIT_FAILURE);
        }
        else if(io_buffer == 0){    //THIS IS SERVER IS CLOSED
            perror("client: connection closed ->");
            break;
        }
        printf("ECHO %s (%d bytes)", buffer, io_buffer);

    }

    printf("Closing the connection \n");
    for(int i=0; i < 5; i++){
        printf(". ");
        usleep(500000);
    }
    close(my_socket);
}

Server implementation:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define LISTENQ 5

int main()
{
    struct sockaddr_in  cli_addr, serv_addr;
    char                buffer[1024];
    int                 serv_socket, cli_socket, clilen, io_buffer;
    int                 tcp_port;

printf("Hello and welcome to the Server mode\n");

//  ASKING FOR PORT NUMBER
    if((serv_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        perror("server: can't open stream socket");
        exit(EXIT_FAILURE);
    }

printf("Please, enter the Server's Port (eg. 1320) \n");
    scanf("%d", &tcp_port);

//  CONFIGURING THE CONNECTION
    serv_addr.sin_family        = AF_INET;
    serv_addr.sin_port          = htons(tcp_port);
    serv_addr.sin_addr.s_addr   = htonl(INADDR_ANY);

//  ASSIGNING A NAME TO THE SOCKET
    if(bind(serv_socket,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){
        perror("server: can't assign a name to the socket");
        exit(EXIT_FAILURE);
    }
printf("Server socket successfully configured\n");

printf("Server listening [Clients allowed: %d]\n", LISTENQ);
    if(listen(serv_socket, LISTENQ) < 0)
    {
        perror("server: fail to listen network");
        exit(EXIT_FAILURE);
    }

//  READ & WRITE STREAM
    while(1){
        //returns a file descriptor for the client
        cli_socket = accept(serv_socket,(struct sockaddr *) &cli_addr,(socklen_t *) sizeof(cli_addr));

        if(cli_socket < 0){
            perror("server: accept error");
            exit(EXIT_FAILURE);
        }
        printf("Server successfully connected to Client\n");

        while(1)
        {

            if ((io_buffer=recv(cli_socket,buffer,sizeof(buffer),0))<0){
                perror("ERROR: recv");
                exit(EXIT_FAILURE);
            }
            printf("\"%s\" received from client", buffer);

            if(strcmp(buffer, "FINISH") == 0)
            {
                break;
            }

            if ((io_buffer=send(cli_socket,buffer,strlen(buffer),0))!=strlen(buffer)){
                perror("ERROR: send");
                exit(EXIT_FAILURE);
            }

            bzero(buffer, sizeof(buffer));
        }

        strcpy(buffer, "OK");
        if ((io_buffer=send(cli_socket, buffer, strlen(buffer), 0)) != strlen(buffer)){
            perror("ERROR: send");
            exit(EXIT_FAILURE);
        }
        printf("\"OK\" message sent to the Client.\n");
        printf("Closing the connection \n");
        for(int i=0; i < 5; i++)
        {
            printf(". ");
            usleep(500000);
        }
        close(cli_socket);
    }
}

回答1:


In your original question, your accept call looks like this:

cli_socket = accept(serv_socket,(struct sockaddr *) &cli_addr,
                   (socklen_t *) sizeof(cli_addr));

This passes "(socklen_t *) sizeof(cli_addr)" as the third parameter to accept. This is expected to be a pointer to the size of the structure. You should be passing in a pointer to a socklen_t containing the size of the structure passed as parameter two. The size you're currently passing in is being interpreted as an address, which is then causing your program to crash when it is referenced. The code should look like this:

socklen_t cli_addr_size = sizeof(cli_addr);
cli_socket = accept(serv_socket,(struct sockaddr *) &cli_addr,
                   &cli_addr_size);


来源:https://stackoverflow.com/questions/37833632/tcp-client-server-bad-address-error-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!