我一直在尝试为Linux编写一个小程序,以检测端口上的客户端连接,例如8080,并在连接时关闭套接字并执行某些程序。
我为端口设置了套接字。 之后,我选择等待传入的客户端连接。
if(select(listener+1, &master, NULL, NULL, NULL) == -1)
{
perror("Server-select() erro!");
exit(1);
}
printf("Close socket...\n");
close(listener);
在此之后,我执行了一个程序,该程序应该读取端口上的数据。
这一切都运行正常,但尝试连接的客户端总是第一次失败,因为,我想当我关闭套接字时,从客户端发送到程序的数据会丢失。 无论如何都要等待端口连接,而不会丢失数据发送? 我在想一些不承认这种关系的事情。
当我按照建议接受()时:
{
struct sockaddr_in clientName = { 0 };
int slaveSocket, clientLength = sizeof(clientName);
(void) memset(&clientName, 0,sizeof(clientName));
slaveSocket = accept(listener,(struct sockaddr *) &clientName,&clientLength);
if (-1 == slaveSocket)
{
perror("accept()");
exit(1);
}
}
printf("Close socket...\n");
close(listener);
if ((child = fork()) == 0) { /* Child process. */
printf("Child: PID of Child = %ld\n", (long) getpid());
execvp(argv[2], &argv[2]); /* arg[0] has the command name. */
/* If the child process reaches this point, then *//* execvp must have failed. */
fprintf(stderr, "Child process could not do execvp.\n");
exit(1);
} else { /* Parent process. */
if (child == (pid_t) (-1)) {
fprintf(stderr, "Fork failed.\n");
exit(1);
} else {
c = wait(&cstatus); /* Wait for child to complete. */
printf("Parent: Child %ld exited with status = %d\n", (long) c,
cstatus);
}
}
执行的shell程序失败: bind()错误(端口号:8554):已在使用的地址 所以我想我需要以某种方式释放端口?
答案 0 :(得分:3)
请参阅此示例如何正确执行此操作:http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/023/2333/2333l1.html
您不要关闭侦听套接字。你调用accept来获取传入连接的新fd,然后fork。分叉后,您可以关闭侦听套接字,并使用accept'ed套接字传输数据。父进程只关闭已接受的套接字并继续侦听。
答案 1 :(得分:1)
由于您不接受传入连接,因此在关闭侦听套接字时必须关闭它。您需要先致电accept()
。