【问题标题】:Connection refused socket programming in C AF_UNIXC AF_UNIX 中的连接拒绝套接字编程
【发布时间】:2015-05-16 16:55:17
【问题描述】:

您好,我正在尝试制作一个简单的程序,它分叉然后应该像客户端/服务器一样运行。这是我的代码:

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);
    }

我不明白为什么当我尝试将客户端连接到服务器时会失败。我收到此错误:连接被拒绝。 我实在找不到问题出在哪里,谢谢您的帮助。

【问题讨论】:

  • 看起来您的第一个问题可能是竞争条件。有什么理由认为客户端在服务器监听之前没有尝试连接?
  • 我想我已经找出了问题所在:我在程序运行时创建了一个套接字,但我没有消除它,所以我有一个名为 mysock 的文件,不会让我的程序运行。如果我手动删除它,代码将完美运行...曾经...我现在该如何解决?

标签: c sockets connection errno


【解决方案1】:

首先,关于分叉然后应该像客户端/服务器一样运行的简单程序:将客户端服务器放在同一个逻辑块中并不是一个好主意。虽然它可以写成语法正确(即它会编译和构建),但我看不出它会如何实用。

有许多教程示例,使用 Posix C 创建单独的服务器和客户端应用程序。 Here is oneHere is anothera 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...

【讨论】:

  • 感谢您的好建议,我没有放置控件,因为我将它发布在那里并且可能有点难以阅读代码,所以我宁愿不检查每个命令。我发现了如何简单地解决我的问题:unlink()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
相关资源
最近更新 更多