我学习网络编程,我有疑问,请帮帮我! 让我来描述我的问题,在基础epoll上我写了tcp服务器。所以它很棒,但是我想做这个服务器多进程,为了实现它我决定使用fd-passing between main process and workers 所以我编写了代码,但似乎它工作不正确。
#define MAX_EVENTS 32
int set_nonblock(int fd){
int flags;
#if defined(O_NONBLOCK)
if (-1 == (flags = fcntl(fd,F_GETFL, 0)))
flags = 0;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#else
flags = 1;
return ioctl(fd, FIONBIO, &flags);
#endif
}
它的功能需要做套接字非阻塞,接下来 它是工人流程的代码
void child(int sock)
{
int fd;
char buf[16];
ssize_t size;
sleep(1);
for (;;) {
size = sock_fd_read(sock, buf, sizeof(buf), &fd);
if (size <= 0)
break;
if (fd != -1) {
static char Buffer[1024];
std::string answer;
int RecvResult = recv(fd,
Buffer, 1024, MSG_NOSIGNAL);
if (RecvResult == 0 && errno != EAGAIN){
shutdown(fd,SHUT_RDWR);
close(fd);
}else if (RecvResult >0){
for (int i = 0; i < RecvResult; ++i){
answer += Buffer[i];
}
int pid = getpid();
std::stringstream ss;
ss << pid;
answer += ss.str() + "\n";
send(fd, answer.c_str(), answer.size(),MSG_NOSIGNAL);
}
}
}
printf("child processes is end\n");
}
那么,主要进程的下一个代码类
struct Descriptors{
int sv[2];
};
class Parent{
public:
static Parent& getInstance(){
static Parent instance;
return instance;
}
Parent(Parent const&) = delete;
void operator=(Parent const&) = delete;
void addFd(int fd){
m_fd.push_back(fd);
};
void run() {
int MasterSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
std::set<int> SlaveSockets;
struct sockaddr_in SockAddr;
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(12347);
SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(MasterSocket, (struct sockaddr *)(&SockAddr), sizeof(SockAddr));
set_nonblock(MasterSocket);
listen(MasterSocket, SOMAXCONN);
int Epoll = epoll_create1(0);
struct epoll_event Event;
Event.data.fd = MasterSocket;
Event.events = EPOLLIN;
epoll_ctl(Epoll, EPOLL_CTL_ADD, MasterSocket, &Event);
size_t index = 0;
while(true){
struct epoll_event Events[MAX_EVENTS];
int N = epoll_wait(Epoll, Events, MAX_EVENTS, -1);
for (size_t i =0; i < N; ++i){
if (Events[i].data.fd == MasterSocket) {
int SlaveSocket = accept(MasterSocket, 0, 0);
set_nonblock(SlaveSocket);
struct epoll_event Event;
Event.data.fd = SlaveSocket;
Event.events = EPOLLIN;
epoll_ctl(Epoll, EPOLL_CTL_ADD, SlaveSocket, &Event);
}else {
char * arg = "1";
ssize_t size = sock_fd_write(m_fd[index], arg, 1,Events[i].data.fd);
index = (1+index) % m_fd.size();
}
}
}
}
private:
Parent(){
m_numCpu = sysconf(_SC_NPROCESSORS_ONLN);
}
int m_numCpu;
std::vector<int> m_fd;
};
void parent(int sock){
Parent::getInstance().addFd(sock);
}
和我的主要功能:
int main(int argc, char **argv){
int numCpu = sysconf(_SC_NPROCESSORS_ONLN);
std::cout << "parent pid = " << getpid() << std::endl;
std::vector<Descriptors> desc;
desc.resize(numCpu);
bool isParent = true;
for (int i = 0; i < numCpu && isParent; ++i){
std::cout << "pid my is = " << getpid() <<std::endl;
int sv[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
perror("socketpair");
exit(1);
}
pid_t forkId = fork();
switch (forkId){
case 0:{
isParent = false;
close(sv[0]);
child(sv[1]);
break;
}
case -1:
perror("fork");
exit(1);
default:
close(sv[1]);
parent(sv[0]);
break;
}
}
if (isParent){
std::cout << "pid parent after create = " << getpid()
<< " parent od parent = " <<getppid() << std::endl;
Parent::getInstance().run();
int status;
waitpid(-1, &status, 0);
}
所以第一个错误是当一个客户端断开连接时,我的服务器变得很奇怪 请问你能帮帮我吗!感谢您的任何建议和任何有用的链接!!!