服务器可以使用相同的套接字将响应发送给客户端吗?如何?

标签 c deadlock sockets

我正在使用 Berkeley 套接字(包括:Internet 域和 Unix 域),我想知道服务器是否可以使用相同的套接字来读取请求并向客户端写入响应。或者客户端应该创建另一个套接字来等待重播,服务器在处理收到的消息后连接到它。

顺便说一下,我说的是面向连接的套接字(流套接字、TCP、...)。

这是简化的服务器代码(为了简单起见,我在这里省略了对系统调用的错误检查):

int main() {

    int server_socket, connected_socket;
    struct sockaddr_in server_addr;
    char buf[1024];
    char aux[256];
    int bytes_read;

    server_socket = socket(AF_INET, SOCK_STREAM, 0);    

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(1234);
    bind(server_socket, &server_addr, sizeof(server_addr))

    listen(server_socket, 5)

    connected_sodket = accept(server_socket, 0, 0);
    do {
        bzero(buf, sizeof(buf));
        bytes_read = read(connected_socket, buf, sizeof(buf));        
    } while (bytes_read > 0);          

    /* Here I want to use connected_socket to write the reply, can I? */

    close(connected_socket);       

    close(server_socket);

    return (EXIT_SUCCESS);
}

这是简化的客户端代码(为了简单起见,我在这里省略了对系统调用的错误检查):

int main() {

    int client_socket;
    struct sockaddr_in server_addr;

    client_socket = socket(AF_INET, SOCK_STREAM, 0);

    hp = gethostbyname("myhost");
    server_addr.sin_family = AF_INET;
    memcpy(&server_addr.sin_addr, hp->h_addr_list[0], hp->h_length);
    server_addr.sin_port = htons(1234);

    connect(client_socket, &server_addr, sizeof(server_addr));

    write(client_socket, MSG, sizeof(MSG));

    /* Here I want to wait for a response from the server using client_socket, can I? */

    close(client_socket);

    return (EXIT_SUCCESS);
}

我可以在服务器端使用 connected_socket 并在客户端端使用 client_socket 来传回响应消息吗?或者我应该使用在“接受”时在服务器中获得的客户端地址来连接到客户端中的套接字吗?

我已经尝试在显示评论的客户端/服务器中使用读/写,但这样两个程序都被阻止,这似乎是一个死锁。

提前致谢! 问候。

最佳答案

应该使用同一个套接字!

您的应用程序协议(protocol)明确定义了客户端和服务器何时应等待数据或相互发送消息;假设一个协议(protocol)只有一个来自客户端的请求和一个来自服务器的响应,以下内容应该成立:


  • 客户端与服务器建立连接;
  • 客户端发送请求(使用 send());
  • 根据协议(protocol),客户端知道服务器将回复;因此它在同一个套接字上等待数据 (recv());
  • 验证响应后,客户端可以关闭套接字。

  • 服务器接受来自客户端的连接;
  • 服务器知道第一步由客户端决定,因此它等待数据 (recv());
  • 服务器验证请求;
  • 服务器现在从协议(protocol)中知道客户端正在等待数据;因此它使用 send() 发送响应;
  • 服务器知道,从协议(protocol)中,没有进一步的步骤;因此它可以关闭套接字。

关于服务器可以使用相同的套接字将响应发送给客户端吗?如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/467396/

相关文章:

c# - 在 MVC 中从同步调用异步而没有等待时,TPL 任务死锁

java - java中的程序化死锁检测

c++ - 在 LSP 中连接到 socks5 代理

c程序中的cmake和readline库

c - in_addr_t inet_ntoa 等类型的地址是什么

c - 发现错误(短定位功能)- C

sockets - iSeries机器上PASE上的网络错误

c - "formatted"C语言

multithreading - 什么是死锁?

linux - Docker 安装套接字卷