Народ помогите...обычная програмка клиента и сервера.Клиент посылает серверу сообщение "Здравствуй мир".При запуске программы клиента выдает :"Ошибка передачи сообщения".Еще такой вопрос:"Сначала нужно запускать программу сервера а потом программу клиента?или наоборот".
Сервер#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define MAXBUF 256char 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 256char 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");
Возможно из-за этого и выдается ошибка.
>Народ помогите...обычная програмка клиента и сервера.Клиент посылает серверу сообщение "Здравствуй мир".При запуске
>программы клиента выдает :"Ошибка передачи сообщения".Еще такой вопрос:"Сначала нужно запускать программу
>сервера а потом программу клиента?или наоборот".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. НО помни, что в этом случае любой пользователь системы сможет присосаться к сокету.
>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.
>>2. n = recvfrom(sockfd, buf, MAXBUF, 0, (struct sockaddr*)&clnt_addr, &caddrlen);
>>
>>ИМХО, зачем мусор записывать, который идет послед strlen(buf) ?
>Это не запись, а чтение :) Тут все нормально.В точку :) Сколько раз убеждаюсь, что нужно сначала умываться, а потом читать почту :)
Сервер:
#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. Затем запускаешь клиент передав ему в качестве аргумента произвольную строку (она будет послана на сервер).
Спасибо большое за помощь.Очень пригодилась.