嗨,我正在尝试制作一个简单的分叉程序,然后像客户端/服务器一样工作。这是我的代码:
int main (){
int sfd,fdc;
struct sockaddr_un sa;
strncpy(sa.sun_path,SOCKNAME,UNIX_PATH_MAX);
sa.sun_family = AF_UNIX;
char buf[N+1];
if (fork() != 0){
sfd = socket(AF_UNIX,SOCK_STREAM,0);
bind (sfd, (struct sockaddr *) &sa ,sizeof(sa));
listen(sfd, SOMAXCONN);
fdc= accept(sfd,NULL,0);
read(fdc,buf,N);
printf("Server got: %s\n",buf);
write(fdc,"bye!",5);
close(fdc);
close(sfd);
exit(EXIT_SUCCESS);
}
else {
sfd = socket(AF_UNIX,SOCK_STREAM,0);
while(connect(sfd, (struct sockaddr *)&sa,sizeof(sa)) == -1){
if (errno == ENOENT){
printf("Aspetto 1 sec\n");
sleep(1);
}
else {perror(NULL); exit(EXIT_FAILURE) ;}
}
write(sfd,"Hallo!",7);
read(sfd,buf,N);
printf("Client got: %s\n",buf);
close(sfd);
exit(EXIT_SUCCESS);
}
我不明白为什么在尝试将客户端连接到服务器时此操作失败。我收到此错误:连接被拒绝。
感谢您的帮助,我真的找不到问题所在。
最佳答案
首先,关于分叉然后应该像客户端/服务器一样工作的简单程序:将客户端和服务器置于同一逻辑块中不是一个好主意。尽管可以将其写成在语法上是正确的(即可以编译和构建),但我不知道它怎么会实用。
有许多教程示例,使用Posix C创建单独的服务器和客户端应用程序。 Here is one。 Here is another和a third。
一个普遍的建议是,在使用具有前提条件的一系列函数(例如套接字的句柄或先前成功调用另一个函数)时,应始终使用返回值。例如,在示例代码的以下行中:
if (fork() != 0){
sfd = socket(AF_UNIX,SOCK_STREAM,0);
bind (sfd, (struct sockaddr *) &sa ,sizeof(sa));
listen(sfd, SOMAXCONN);
fdc= accept(sfd,NULL,0);
您选择验证的唯一一行是fork的结果(很好)。但是,您还应该检查其他每个结果,并将结果作为继续进行下一步的先决条件。
至少是这样的:
if (fork() != 0)
{
sfd = socket(AF_UNIX,SOCK_STREAM,0);
if(sfd < 0)
{
//notify user
return -1;
}
ret = bind (sfd, (struct sockaddr *) &sa ,sizeof(sa));
if(ret < 0)
{
//check value of errno, and notify user
return -1;
}
ret = listen(sfd, SOMAXCONN);
if(ret < 0)
{
//check value of errno, and notify user
return -1;
}
new_s= accept(sfd,NULL,0);
if(new_s < 0)
{
//check value of errno, and notify user
return -1;
}
// continue...