我正在使用 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/