套接字服务器线程
C++ - Thread for socket server
我正在尝试实现一个服务器,它在自己的线程中运行。稍后,服务器应该与另一个线程一起工作。这可能吗?
我当前尝试实现这个:
主要#include "EtherServer.h"
int main(int argc, char *argv[])
{
EtherServer* es = new EtherServer();
es->init();
return 0;
}
Server.h
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#ifndef ETHERSERVER_H_
#define ETHERSERVER_H_
class EtherServer
{
public:
bool init();
static void* runServer(void *arg);
static void sigchld_handler(int s);
static void* get_in_addr(struct sockaddr *sa);
static int s_sockfd;
private:
};
#endif /* ETHERSERVER_H_ */
Server.cpp
#include "EtherServer.h"
#define PORT "31107" // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
int EtherServer::s_sockfd = 0;
void EtherServer::sigchld_handler(int s)
{
// waitpid() might overwrite errno, so we save and restore it:
int saved_errno = errno;
while(waitpid(-1, NULL, WNOHANG) > 0);
errno = saved_errno;
}
// get sockaddr, IPv4 or IPv6:
void* EtherServer::get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
bool EtherServer::init()
{
int rv;
int yes=1;
struct addrinfo hints, *servinfo, *p;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %sn", gai_strerror(rv));
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next)
{
if ((EtherServer::s_sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(EtherServer::s_sockfd, SOL_SOCKET, SO_REUSEADDR, yes,
sizeof(int)) == -1)
{
perror("setsockopt");
exit(1);
}
if (bind(EtherServer::s_sockfd, p->ai_addr, p->ai_addrlen) == -1)
{
close(EtherServer::s_sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(servinfo); // all done with this structure
if (p == NULL) {
fprintf(stderr, "server: failed to bindn");
exit(1);
}
if (listen(EtherServer::s_sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
struct sigaction sa;
sa.sa_handler = EtherServer::sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
pthread_attr_t attr_baseb;
(void)pthread_attr_init(&attr_baseb);
(void)pthread_attr_setdetachstate(&attr_baseb, PTHREAD_CREATE_DETACHED);
(void)pthread_create(NULL, &attr_baseb, &runServer, (void *)this);
}
void* EtherServer::runServer(void *arg)
{
int new_fd; // listen on sock_fd, new connection on new_fd
//struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // connector's address information
socklen_t sin_size;
char s[INET6_ADDRSTRLEN];
printf("server: waiting for connections...n");
while(1) { // main accept() loop
sin_size = sizeof their_addr;
sleep(1);
new_fd = accept(EtherServer::s_sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family, EtherServer::get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
printf("server: got connection from %sn", s);
if (!fork()) { // this is the child process
int n;
char buffer[256];
bzero(buffer, 256);
close(EtherServer::s_sockfd); // child doesn't need the listener
while (n = read(new_fd, buffer, 255) > 0)
{
if (send(new_fd, buffer, 255, 0) == -1)
perror("send");
}
close(new_fd);
exit(0);
sleep(1);
}
close(new_fd); // parent doesn't need this
}
}
你的线程作为main()的子线程运行。当你从main返回时,它的子线程也会被杀死。
main必须执行自己的等待操作,而不是返回,因此只有当所有子线程都完成时,它才会干净地退出。
相关文章:
- C/C++ Linux 上的多线程服务器/客户端崩溃
- 设计低线程争用的多线程聊天服务器
- C++服务器上的线程同步
- C++多线程服务器
- 卫生多线程服务器
- 在多线程c++服务器应用程序中处理非常量全局配置
- 多线程服务器在一个线程中处理多个客户端
- 在 GDB 中调试多线程服务器 - 查找每个线程的状态.执行时继续并停止
- 多线程服务器在不等待客户端连接的情况下退出
- 多线程服务器不工作
- 多线程服务器
- 调试多线程服务器
- 套接字在多线程服务器中不能正确接受
- C++具有 Winsock 和 std::thread 的多线程服务器
- c++中的多线程服务器,如何很好地终止线程和清理
- 多线程服务器设计
- 创建多线程服务器的问题
- 使用QtConcurrent::运行的线程服务器
- 带有std::线程强制转换变量的c++多线程服务器
- 多线程服务器与boost.Asio