URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 4933
[ Назад ]

Исходное сообщение
"клиент - сервер"

Отправлено Silence , 13-Дек-05 03:02 
Народ помогите...обычная програмка клиента и сервера.Клиент посылает серверу сообщение "Здравствуй мир".При запуске программы клиента выдает :"Ошибка передачи сообщения".Еще такой вопрос:"Сначала нужно запускать программу сервера а потом программу клиента?или наоборот".


Сервер

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define MAXBUF 256

char buf [MAXBUF];

main()
{
    struct sockaddr_un serv_addr, clnt_addr;
    int sockfd;
    int saddrlen,caddrlen,max_caddrlen,n;
    if((sockfd = socket(AF_UNIX, SOCK_DGRAM,0)) < 0)
    {
        printf("Невозможно создать сокет‚\n");
        exit(1);
    }
    unlink("./new/7/serv");
    bzero(&serv_addr,sizeof(serv_addr));
    serv_addr.sun_family = AF_UNIX;
    strcpy(serv_addr.sun_path,"./new/7/serv");
    saddrlen = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path);
    if(bind(sockfd,(struct sockaddr *)&serv_addr, saddrlen) < 0)
    {
        printf("Ошибка связывания сокета\n");
        exit(1);
    }
    max_caddrlen = sizeof(clnt_addr);
        for( ; ; )
    {
        caddrlen = max_caddrlen;
        n = recvfrom(sockfd, buf, MAXBUF, 0, (struct sockaddr*)&clnt_addr, &caddrlen);
        if(n < 0)
        {
            printf("Ошибка приема\n");
            exit(1);
        }
        if(sendto(sockfd, buf, n, 0, (struct sockaddr*)&clnt_addr,caddrlen) != n)
        {
            printf("Ошибка передачи\n");
            exit(1);
        }
    }
}


Клиент

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

char *msg = "Зравствуй мир! \n";
#define MAXBUF 256

char buf[MAXBUF];
main()
{
    struct sockaddr_un  serv_addr , clnt_addr;
    int sockfd;
    int saddrlen, caddrlen, msglen,n;
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sun_family = AF_UNIX;
    strcpy(serv_addr.sun_path, "./new/7/serv");
    saddrlen = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path);
    if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
    {
        printf("Невозможно создать сокет‚ \n");
        exit(1);
    }
    bzero(&clnt_addr, sizeof(clnt_addr));
    clnt_addr.sun_family = AF_UNIX;
    strcpy(clnt_addr.sun_path, "/new/7/client");
    mktemp(clnt_addr.sun_path);
    caddrlen = sizeof(clnt_addr.sun_family) + strlen(clnt_addr.sun_path);
    if(bind(sockfd,(struct sockaddr*)&clnt_addr,caddrlen) < 0)
    {
        printf("Ошибка связывания сокета\n");
        exit(1);
    }
    if(sendto(sockfd, msg, msglen, 0,(struct sockaddr*)&serv_addr,saddrlen) != msglen)
    {
        printf("Ошибка передачи сообщения\n");
        exit(1);
    }
    if((n = recvfrom(sockfd, buf, MAXBUF,0,NULL,0)) < 0)
    {
        printf("Ошибка получения сообщения\n");
        exit(1);
    }
    printf("Эхо: %s\n", buf);
    close(sockfd);
    unlink(clnt_addr.sun_path);
    exit(0);
}

И еще меня интересует какой путь нужно устанавливать в этих строчках?

unlink("./new/7/serv");
strcpy(serv_addr.sun_path,"./new/7/serv");
strcpy(serv_addr.sun_path, "./new/7/serv")
strcpy(clnt_addr.sun_path, "/new/7/client");
strcpy(clnt_addr.sun_path, "/new/7/client");
Возможно из-за этого и выдается ошибка.


Содержание

Сообщения в этом обсуждении
"клиент - сервер"
Отправлено chip , 13-Дек-05 11:05 
>Народ помогите...обычная програмка клиента и сервера.Клиент посылает серверу сообщение "Здравствуй мир".При запуске
>программы клиента выдает :"Ошибка передачи сообщения".Еще такой вопрос:"Сначала нужно запускать программу
>сервера а потом программу клиента?или наоборот".

1. Для error handling лучше использовать perror или strerror. И в любом случае output device = stderr, т.е:

fprintf(stderr, ...), но никак не printf
2. n = recvfrom(sockfd, buf, MAXBUF, 0, (struct sockaddr*)&clnt_addr, &caddrlen);

ИМХО, зачем мусор записывать, который идет послед strlen(buf) ?

3. Запускается сервер первым.

>И еще меня интересует какой путь нужно устанавливать в этих строчках?
>
>unlink("./new/7/serv");
>strcpy(serv_addr.sun_path,"./new/7/serv");
>strcpy(serv_addr.sun_path, "./new/7/serv")
>strcpy(clnt_addr.sun_path, "/new/7/client");
>strcpy(clnt_addr.sun_path, "/new/7/client");
>Возможно из-за этого и выдается ошибка.

Путь у клиента и сервера должны совпадать. Разумнее в этом случае использовать абсолютный путь. Например, /tmp/srv.sock. НО помни, что в этом случае любой пользователь системы сможет присосаться к сокету.


"клиент - сервер"
Отправлено enot , 13-Дек-05 11:51 
>2. n = recvfrom(sockfd, buf, MAXBUF, 0, (struct sockaddr*)&clnt_addr, &caddrlen);
>
>ИМХО, зачем мусор записывать, который идет послед strlen(buf) ?
Это не запись, а чтение :) Тут все нормально.

А перед следующей строкой в клиенте не определено значение msglen.
Надо определить msglen = strlen(msglen);
> if(sendto(sockfd, msg, msglen, 0,(struct sockaddr*)&serv_addr,saddrlen) != msglen)


>Путь у клиента и сервера должны совпадать. Разумнее в этом случае использовать
>абсолютный путь. Например, /tmp/srv.sock. НО помни, что в этом случае любой
>пользователь системы сможет присосаться к сокету.
Не любой, а только тот кто имеет права на чтение/запись в/из /tmp/srv.sock.


"клиент - сервер"
Отправлено chip , 13-Дек-05 12:01 
>>2. n = recvfrom(sockfd, buf, MAXBUF, 0, (struct sockaddr*)&clnt_addr, &caddrlen);
>>
>>ИМХО, зачем мусор записывать, который идет послед strlen(buf) ?
>Это не запись, а чтение :) Тут все нормально.

В точку :) Сколько раз убеждаюсь, что нужно сначала умываться, а потом читать почту :)


"клиент - сервер"
Отправлено chip , 13-Дек-05 11:58 
Сервер:
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>


#define _SOCK_PATH "/tmp/srv.sock"

int
srv(int clientfd) {
  while (1) {
    int length;
    char *text;

    /* $-1¨´¨Û¨Ø¨Ý¨Ð ¨á¨Þ¨Þ¨Ñ¨é¨Õ¨Ý¨Ø¨ï */
    if (read(clientfd, &length, sizeof(&length)) == 0)
      return 0;
    text = (char *) malloc(length);
    read(clientfd, text, length);
    fprintf(stderr, "%s\n", text);
    free(text);
    if (!strcasecmp(text, "quit"))
      return 1;
  }
}
    

int
main(int argc, char *argv[]) {
  int sockfd, rv, quit_flag;
  struct sockaddr_un srv_addr;

  sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);
  if (sockfd < 0)
    err(EX_UNAVAILABLE, "socket");
  unlink(_SOCK_PATH);
  memset(&srv_addr, 0, sizeof(struct sockaddr_un));
  srv_addr.sun_family = AF_LOCAL;
  strncpy(srv_addr.sun_path, _SOCK_PATH, strlen(_SOCK_PATH) + 1);
  rv = bind(sockfd, (struct sockaddr *) &srv_addr, SUN_LEN(&srv_addr));
  if (rv < 0) {
    close(sockfd);
    err(EX_UNAVAILABLE, "bind");
  }
  /* $-1¨¾¨Ö¨Ø¨Ô¨Ð¨Ý¨Ø¨Õ ¨×¨Ð¨ß¨à¨Þ¨á¨Þ¨Ò */
  listen(sockfd, 5);

  do {
    struct sockaddr_un client_addr;
    socklen_t client_addr_len;
    int clientfd;

    clientfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
    quit_flag = srv(clientfd);
    close(clientfd);
  } while (!quit_flag);
  close(sockfd);
  unlink(_SOCK_PATH);

  return 0;
}


Клиент:

#include <err.h>
#include <stdio.h>
#include <string.h>
#include <sysexits.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define _SOCK_PATH "/tmp/srv.sock"

int
main(int argc, char *argv[]) {
  int sockfd, rv;
  const char * const message = argc > 1 ? argv[1] : "Null message";
  struct sockaddr_un client_addr;

  sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);
  if (sockfd < 0)
    err(EX_UNAVAILABLE, "socket");
  memset(&client_addr, 0, sizeof(struct sockaddr_un));
  client_addr.sun_family = AF_LOCAL;
  strncpy(client_addr.sun_path, _SOCK_PATH, strlen(_SOCK_PATH) + 1);
  rv = connect(sockfd, (struct sockaddr *) &client_addr, SUN_LEN(&client_addr));
  if (rv < 0)
    err(EX_UNAVAILABLE, "connect");

  do {
    int length = strlen(message) + 1;
    write(sockfd, &length, sizeof(length));
    write(sockfd, message, length);
  } while (0);
  close(sockfd);
  
  return 0;
}

Запускаешь сначала сервер, он начинает прослушивать /tmp/srv.sock. Затем запускаешь клиент передав ему в качестве аргумента произвольную строку (она будет послана на сервер).


"клиент - сервер"
Отправлено Silence , 14-Дек-05 20:39 
Спасибо большое за помощь.Очень пригодилась.