TCP 客户端-服务器“错误地址"错误(在 C 中) [英] TCP Client-Server "bad address" error (in C)

查看:52
本文介绍了TCP 客户端-服务器“错误地址"错误(在 C 中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然它似乎被正确实现,当我使用环回地址建立连接时,它不断返回ERROR(127.0.0.1).

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).

除了简单的 TCP Client/Server 连接之外,我还添加了一个额外的案例:

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

如果客户端尝试发送数据但发现连接已关闭,则它也已关闭.我通过检查接收到的数据是否等于 0 (recv) 来执行它.

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).

给定错误:

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

客户端实现:

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

服务器实现:

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

推荐答案

在您的原始问题中,您的 accept 调用如下所示:

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

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

这将传递(socklen_t *) sizeof(cli_addr)"作为要接受的第三个参数.这应该是一个指向结构大小的指针.您应该传入一个指向 socklen_t 的指针,该指针包含作为参数二传递的结构的大小.您当前传入的大小被解释为地址,这会导致您的程序在引用时崩溃.代码应如下所示:

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

这篇关于TCP 客户端-服务器“错误地址"错误(在 C 中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆