服务器和多个客户端使用pthreads和select()
server and multiple clients using pthreads and select()
考虑下一个代码 -
int get_ready_connection(int s) {
/* socket of connection */
int caller;
if ((caller = accept(s,NULL,NULL)) < SUCCESS)
{
server_log->write_to_log(sys_call_error(SERVER, "accept"));
return FAILURE;
}
return caller;
}
int establish_connection(sockaddr_in& connection_info)
{
// Create socket
if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < SUCCESS)
{
server_log->write_to_log(sys_call_error(SERVER, "socket"));
return FAILURE;
}
// Bind `sock` with given addresses
if (bind(server_sock, (struct sockaddr *) &connection_info,
sizeof(struct sockaddr_in)) < SUCCESS)
{
close(server_sock);
server_log->write_to_log(sys_call_error(SERVER, "bind"));
return FAILURE;
}
// Max # of queued connects
if (listen(server_sock, MAX_PENDING_CONNECTIONS) < SUCCESS)
{
server_log->write_to_log(sys_call_error(SERVER, "listen"));
return FAILURE;
}
// Create a set of file descriptors and empty it.
fd_set set;
bool is_inside;
int ret_val;
while(true)
{
FD_ZERO(&set);
FD_SET(STDIN_FILENO, &set);
FD_SET(server_sock, &set);
struct timeval tv = {2, 0};
ret_val = select(server_sock + 1, &set, NULL, NULL, &tv); // TODO ret_val
is_inside = FD_ISSET(STDIN_FILENO, &set);
if(is_inside)
{
// get user input
string user_input;
getline(cin, user_input);
if ((strcasecmp(user_input.c_str(), EXIT_TEXT) == 0))
{
return SUCCESS;
}
}
is_inside = FD_ISSET(server_sock, &set);
if(is_inside)
{
// get the first connection request
int current_connection = get_ready_connection(server_sock);
if (current_connection == FAILURE) {
free_allocated_memory();
exit_write_close(server_log, sys_call_error(SERVER, "accept"),
ERROR);
}
// if exit was not typed by the server's stdin, process the request
pthread_t thread;
// create thread
if (pthread_create(&thread, NULL, command_thread_func, ¤t_connection) != 0)
{
free_allocated_memory();
exit_write_close(server_log, sys_call_error(SERVER, "pthread_create"), ERROR);
}
}
}
}
所有我都在尝试做的是"收听" stdin,以供用户在服务器的外壳中键入'exit',并等待客户从其外壳中传递命令(每次服务器都从从用户,服务器解析它,服务器创建一个处理命令执行的线程)为了同时这样做,我使用了select()。
当我使用一个线程时,一切都是完美的。但是问题是当我连接另一个客户端时,我会得到SEG错误。我怀疑问题就在这里。有任何建议吗?
很难知道这是否是您的确切问题,但这绝对是 a 问题:
您无法调用pthread_create
,并提供指向堆栈变量(¤t_connection
)的指针作为线程函数的参数。一方面,一旦父母退出该范围,这会立即遭到破坏。
其次,它将在下一个呼叫get_ready_connection
中覆盖。
相关文章:
- C++ PTHREADS - 无效转换无效*(*)()到无效*(*)(无效*)
- SQLite3 在 c++ 中输出 SELECT 上的空列表
- 如何在 sys/select.h 中正确使用
- 为什么我不能让 3 个网络摄像头与 pthreads 并行运行?
- 获取具有字段名称的 SELECT 字段类型,并带有 MariaDB C++连接器
- 如何使用 Pthreads 并行化图像翻转?
- 如何使用 pthreads 以正确的方式设置两个线程之一的优先级
- UDP 套接字 select() 在某些情况下无延迟(超时)返回 1
- Winsock2 select():同一个套接字上可能有多个事件吗?
- Winsock2 select() 返回 WSAEINVAL(错误 10022)
- 将 select() 与非基于文件描述符的输入一起使用
- Winsock2 select() 函数:传递 {0, 0} 作为超时参数
- 如何在C++应用程序中设置"Select Precision"光标?
- C++11 中对超载'ref(Select::Expressions::Code&)'的调用模棱两可
- 使用 select() 管理多个套接字
- 如何应用注册表模式使"select class depend on input"遵守开放封闭原则?
- 使用 Select 多路复用未命名的管道和其他文件描述符
- 互斥体作为使用 pthreads 的类成员
- C++,pthreads:如何从多个线程停止工作线程
- 服务器和多个客户端使用pthreads和select()