在 C 中重用端口和地址的客户端-服务器程序

标签 c sockets client-server

我需要重新创建一个客户场景,其中当我们建立新连接时,会重复使用相同的 ip:port 对。

我想根据这个场景创建一个程序:
客户端使用 XXXX 端口与服务器建立连接。
客户端终止连接。
客户端使用相同的端口 XXXX 与服务器建立另一个连接。

我修改了简单的服务器/客户端代码,例如,我在客户端代码上的accept()之前调用了bind()。当我运行第一轮客户端程序时,它可以工作,但在第二轮中,服务器接受连接,但没有消息从客户端传递到服务器。

有人可以查看代码并帮助我吗?

服务器.c

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

int Create_Socket(void)
{
    int c_socket;
    printf("Creating Socket\n");

    c_socket = socket(AF_INET, SOCK_STREAM, 0);

    return c_socket;
}


int Bind_Socket(int socket)
{
    int bind_s = -1;
    int server_port = 7777;
    struct sockaddr_in server = {0};
    printf("Creating bind\n");

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("22.0.0.1");
    server.sin_port = htons(server_port);

    bind_s = bind(socket, (struct sockaddr *)&server, sizeof(server));

    return bind_s;
}


int main(int argc, char *argv[])
{
    int socket_description, socket, client_length, read_size;

    struct sockaddr_in server_address, client_address;

    char client_message[200] = {0};

    char message[100] = {0};

    const char *pMessage = "Hello Vishnu Vijayan";


    //Create Socket
    socket_description = Create_Socket();
    if(socket_description == -1)
    {
        printf("Could not create socket\n");
        return 1;
    }
    printf("Socket Created\n");


    //Bind Socket
    if(Bind_Socket(socket_description) < 0)
    {
        perror("Bind failed");
        return 1;
    }
    printf("Bind done\n");

    listen(socket_description, 3);


    while(1)
    {
        printf("Waiting for incoming connections.... \n");

        client_length = sizeof(struct sockaddr_in);

        //accept connection from an incoming client
        socket = accept(socket_description, (struct sockaddr *)&client_address, (socklen_t*)&client_length);

        if(socket < 0)
        {
            perror("Accept failed");
            return 1;
        }
        printf("Connection accepted\n");


        memset(client_message, '\0', sizeof(client_message));
        memset(message, '\0', sizeof(message));

        //Receive a reply from client
        if(recv(socket, client_message, 200, 0) < 0)
        {
            printf("recv failed\n");
            break;
        }
        printf("Client reply : %s\n", client_message);

        strcpy(message, pMessage);


        //Send some data
        if(send(socket, message, strlen(message), 0) < 0)
        {
            printf("Send failed\n");
            return 1;
        }

        close(socket);
        sleep(1);
    }

    return 0;
}

客户端.c

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


int Bind_Socket(int socket)
{
        int bind_s = -1;
        int client_port = 7777;
        struct sockaddr_in client = {0};
        printf("Creating bind\n");

        int reuse = 1;

        if(setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
        {
                perror("SO_REUSEADDR failed");
                return -1;
        }

        if(setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
        {
                perror("SO_REUSEPORT failed");
                return -1;
        }

        client.sin_family = AF_INET;
        client.sin_addr.s_addr = inet_addr("20.0.0.1");
        client.sin_port = htons(client_port);

        bind_s = bind(socket, (struct sockaddr *)&client, sizeof(client));

        return bind_s;
}



int Receive_Socket(int socket, char* from_server, int length)
{
    int receive_s = 1;

    receive_s = recv(socket, from_server, length, 0);

    printf("Response : %s\n", from_server);

    return receive_s;   
}


int Send_Socket(int socket, char *send_to_server, int length)
{
    int send_s = -1;

    send_s = send(socket, send_to_server, length, 0);

    return send_s;
}


int Connect_Socket(int socket)
{
    int connect_s = -1;
    int server_port = 7777;
    struct sockaddr_in server = {0};
    printf("Connecting socket\n");

    server.sin_addr.s_addr = inet_addr("22.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons(server_port);

    connect_s = connect(socket, (struct sockaddr *)&server, sizeof(struct sockaddr_in));

    return connect_s;
}


int Create_Socket(void)
{
    int c_socket;
    printf("Creating Socket\n");

    c_socket = socket(AF_INET, SOCK_STREAM, 0);

    return c_socket;
}

int main(int argc, char *argv[])
{
    int socket, read_size;

    struct sockaddr_in server_address;

    char send_to_server[100] = {0};

    char server_reply[200] = {0};


    //Create Socket
    socket = Create_Socket();
    if(socket == -1)
    {
        printf("Could not create socket\n");
        return 1;
    }
    printf("Created Socket\n");


    //Bind Socket
   if(Bind_Socket(socket) < 0)
   {
        perror("Bind failed");
       return 1;
   }
   printf("Bind done\n");


    //Connect to server
    if(Connect_Socket(socket) < 0)
    {
        perror("Connect failed");
        return 1;
    }
    printf("Successfully connected with server\n");

    printf("Enter the message: ");
    gets(send_to_server);

    //Send data to server
    Send_Socket(socket, send_to_server, strlen(send_to_server));

    //Receive data from server
    read_size = Receive_Socket(socket, server_reply, 200);

    printf("Server Response : %s\n\n", server_reply);

    close(socket);

    return 0;
}

最佳答案

您可能想阅读以下答案:
https://stackoverflow.com/a/14388707/15809

特别是有关在 TIME_WAIT 状态下关闭 TCP 套接字的说明,以及 SO_REUSEPORT 如何在 Linux 下实现某种负载平衡。我认为这两种效应中的任何一种都可能在这里发挥作用。

关于在 C 中重用端口和地址的客户端-服务器程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52925391/

相关文章:

c - 链接单独的二进制文件

c - 将 CompletionRoutine 与多个套接字一起使用时如何同步 WSARecvFrom() 的处理

c - 无法将 ip 地址从字符串复制到 sockaddr_in

php - 客户端上的php或javascript可以链接到远程服务器数据库吗?

c# - 如何在应用程序之间同步 ObservableCollection

JAVA KeyEvent序列化错误

c++ - 在不同的 GPU 上初始化结构

c - 当在 userdata 上调用 __len 元方法时,Lua 将两个参数传递给 C,nil 和 userdata。什么是零?

c - 我应该在 Visual Studio 中投 void** 返回吗

c - ws ://in a C program