2015-05-16 3 views
0

Привет, я пытаюсь создать простую программу, которая вилки, а затем должна действовать как клиент/сервер. Вот мой код:Соединение отказало программированию сокета в C AF_UNIX

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

Я не понимаю, почему это происходит, когда я пытаюсь подключить клиента к серверу. Я получил эту ошибку: Connection Refused. Я не могу найти, где проблема, спасибо за вашу помощь.

+0

Похоже, ваша первая проблема может быть состояние гонки. Есть ли причина думать, что клиент не пытается подключиться до того, как сервер прослушивает? – antron

+0

Я думаю, что я понял, в чем проблема: я создаю сокет, когда программа запускается, но потом я не исключаю его, поэтому у меня есть файл под названием mysock и не запускает мою программу. Если я удалю его вручную, код будет работать отлично ... один раз ... как я могу решить это сейчас? – Levenlol

ответ

0

Во-первых, относительно простой программы, которая разветвляется, а затем должен действовать как клиент/сервер: наличие клиента и сервер в том же логическом блоке не является хорошей идеей. хотя он может быть написан как синтаксически правильный (т. е. он будет компилировать и строить), я не вижу, как это когда-либо будет практичным.

Существует много примеров учебников, в которых используется 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); 

единственная линия, которую Вы хотите проверить, является результатом вилки (что хорошо). Но вы также должны проверить результаты каждого из других, используя результаты в качестве предварительного условия перехода к следующему шагу.

В самом крайнем случае что-то вроде этого:

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... 
+0

спасибо за ваш хороший совет, я не поставил элементы управления, потому что я разместил его там и мог быть немного сложнее прочитать код, поэтому лучше не проверять каждую команду. Я выяснил, как решить мою проблему простым использованием: unlink(). – Levenlol