mmu*_*lva 12 c sockets deadlock
我正在使用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);
}
Run Code Online (Sandbox Code Playgroud)
这是简化的客户端代码(为了简单起见,我省略了对系统调用的错误检查):
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);
}
Run Code Online (Sandbox Code Playgroud)
我可以connected_socket在服务器和client_socket客户端中使用来传回响应消息吗?或者我应该在"接受"连接到客户端的套接字时使用我在服务器中获得的客户端地址?
我已经尝试在显示注释的客户端/服务器中使用read/wrint,但这样两个程序都被阻塞,这似乎是一个死锁.
谢谢提前!问候.
Fed*_*oni 10
你应该使用相同的插座!
您的应用程序协议明确定义了客户端和服务器何时应该等待数据或相互发送消息; 假设一个协议只有来自客户端的一个请求和一个来自服务器的响应,则应该包含以下内容:
您可以使用相同的套接字但是您的程序设置为让服务器在尝试回复之前读取客户端发送的所有内容.因此,服务器中的循环将无法完成,直到客户端关闭其套接字的写入端,因此服务器获得EOF(读取0字节),因此服务器将永远不会发回其响应.
有几种方法可以解决这个问题.
shutdown(client_socket, SHUT_WR)半关闭套接字.然后服务器将看到EOF(并且循环将完成),但是套接字上的另一个方向仍将打开以进行回复.