我有两个进程:守护进程
和客户端
。两者是不同的套接字。最初我通过执行守护进程套接字
./daemon
然后 ./client
.
但我希望守护进程应该始终在后台监听来自客户端的请求。因此,我尝试使用 fork() 创建这样一个过程。
我刚刚编辑了原始代码。
现在我可以编译守护程序文件并创建可执行守护程序
。
但是当我发送请求./client
时它没有响应。并显示连接套接字 111 时出错
。
守护进程
正在监听1104
,并且客户端在同一端口上发送请求。
当我执行 ./daemon
时,它说
绑定(bind)到套接字时出错,请确保没有其他东西正在监听此端口 22n
意味着它在后台运行但不响应请求。 代码:
#include <fcntl.h>
#include <string.h>
#include <algorithm>
#include "dictionary_exclude.h"
#pragma GCC diagnostic ignored "-Wwrite-strings"
#define CHECK_THROW(condition, code) if(condition) throw code
void *SocketHandler(void *);
int OpenSocket();
int main(int argv, char **argc)
{
int host_port = 1104;
char buf[20];
int k;
struct sockaddr_in my_addr;
int hsock;
int *p_int;
int err;
socklen_t addr_size = 0;
int *csock;
sockaddr_in sadr;
pthread_t thread_id = 0;
try {
pid_t pid = fork();
CHECK_THROW(pid < 0, -5);
if (pid == 0) {
mode_t umask(mode_t mask);
pid_t childid = setsid();
hsock = OpenSocket(); // Function call for hsock
CHECK_THROW(listen(hsock, 10) == -1, -4);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) {
fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
exit(EXIT_SUCCESS);
}
if (listen(hsock, 10) == -1) {
fprintf(stderr, "Error listening %dn", errno);
exit(EXIT_SUCCESS);
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
while (true) {
printf("waiting for a connectionnn");
csock = (int *) malloc(sizeof(int));
if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) {
printf("---------------------nReceived connection from %sn", inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
} else {
fprintf(stderr, "Error accepting %dn", errno);
}
} //while end
} //if (pid) end
} //try
catch(int ierror) {
switch (ierror) {
case -4:
fprintf(stderr, "Error listening %dn", errno);
break;
case -7:
fprintf(stderr, "Error accepting %dn", errno);
break;
}
}
}
int OpenSocket()
{
// Create your socket and return the socket handle from this function
int hsock;
int *p_int;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if (hsock == -1) {
printf("Error initializing socket %dn", errno);
exit(EXIT_SUCCESS);
}
p_int = (int *) malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) {
printf("Error setting options %dn", errno);
free(p_int);
exit(EXIT_SUCCESS);
}
free(p_int);
return hsock;
}
void *SocketHandler(void *lp)
{
//some procesing
}
有人可以说上面的代码有什么问题吗?
原始代码是:
int main(int argv, char **argc)
{
int host_port = 1104;
char buf[20];
int k;
struct sockaddr_in my_addr;
int hsock;
int *p_int;
int err;
socklen_t addr_size = 0;
int *csock;
sockaddr_in sadr;
pthread_t thread_id = 0;
try {
pid_t pid = fork();
CHECK_THROW(pid < 0, -5);
if (pid == 0) {
mode_t umask(mode_t mask);
pid_t childid = setsid();
hsock = OpenSocket(); // Function call for hsock
CHECK_THROW(listen(hsock, 10) == -1, -4);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) {
fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
exit(EXIT_SUCCESS);
}
if (listen(hsock, 10) == -1) {
fprintf(stderr, "Error listening %dn", errno);
exit(EXIT_SUCCESS);
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
while (true) {
printf("waiting for a connectionnn");
csock = (int *) malloc(sizeof(int));
if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) {
printf("---------------------nReceived connection from %sn", inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
} else {
fprintf(stderr, "Error accepting %dn", errno);
}
} //while end
} //if (pid) end
} //try
catch(int ierror) {
switch (ierror) {
case -4:
fprintf(stderr, "Error listening %dn", errno);
break;
case -7:
fprintf(stderr, "Error accepting %dn", errno);
break;
}
}
}
int OpenSocket()
{
// Create your socket and return the socket handle from this function
int hsock;
int *p_int;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if (hsock == -1) {
printf("Error initializing socket %dn", errno);
exit(EXIT_SUCCESS);
}
p_int = (int *) malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) {
printf("Error setting options %dn", errno);
free(p_int);
exit(EXIT_SUCCESS);
}
free(p_int);
return hsock;
}
void *SocketHandler(void *lp)
{
//some procesing
}
最佳答案
您在调用 bind
之前调用 listen
- 您应该先调用 bind
。
实际上,您在调用 bind
之前和之后调用了 listen
两次。删除第一个调用。
hsock = OpenSocket();
// remove this line:
CHECK_THROW(listen(hsock, 10) == -1, -4);
my_addr.sin_family = AF_INET;
另一项改进:使用 strerror
或 perror
生成错误消息,以便您获得用户友好的消息。例如:
perror("Error binding to socket");
exit(EXIT_SUCCESS);
关于c++ - 守护进程套接字在后台监听请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18961663/