Автор Тема: Пишу клиент-серверное приложение для сокетов. Ругается компилятор  (Прочитано 7540 раз)

Оффлайн ALexeMiK

  • Участник
  • *
  • Сообщений: 132
    • Страница в ВК
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdlib.h>

#define PORTNUM 1500
 int nport;

 struct hostent *hp;
 
int main(argc, argv)

int argc;
char *argv[];
{
 int s, ns;
 int pid;
 char buf[80], hname[80];
/*Преобразуем порядок следования байтов к сетевому формату*/
  nport = PORTNUM;
  nport = htons((u_short)nport);
/*Создадим сокет использующий протокол TCP*/
  if ((s=socket(AF_INET, SOCK_STREAM, 0))==-1)
 {
        perror("Ошибка вызова socket()");
        exit(1);
 }
//Зададим адрес коммуникационного узла
 struct serv_addr;
 struct clnt_addr;
 memset(&serv_addr,0, sizeof(serv_addr));
 serv_addr.sin_family = AF_INET;
 serv_addr.s_addr = INADDR_ANY;
 serv_addr.sin_port = nport ;
//Свяжем сокет с этим адресом
if(bind(s,(struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1)
 {
        perror("Ошибка вызова bind()");
        exit(1);
 }


 return 0;
}

компилятор ругается
server.c: In function ‘main’:
server.c:36:10: error: ‘serv_addr’ undeclared (first use in this function)
  memset(&serv_addr,0, sizeof(serv_addr));
          ^~~~~~~~~
server.c:36:10: note: each undeclared identifier is reported only once for each function it appears in

В чем ошибка? Взял текст из книги Андрея Робачевского -Операционная система UNIX

Оффлайн yaleks

  • Мастер
  • ***
  • Сообщений: 6 242
в том что вы не описали serv_addr, а компиляторы стали на такое сильно ругаться.

Оффлайн trs

  • Участник
  • *
  • Сообщений: 287
Взял текст из книги Андрея Робачевского -Операционная система UNIX
Нашёл эту книгу в pdf. Исходник там отличается от опубликованного. При копировании часть текста не попадает в буфер обмена.
Смотрите внимательнее.
struct sockaddr_in serv_addr, clnt_addr;

serv_addr.sin_addr.s_addr = INADDR_ANY;

Оффлайн ALexeMiK

  • Участник
  • *
  • Сообщений: 132
    • Страница в ВК
Да. Я не описал serv_addr.
НО. Эта структура не описана в исходниках данной программы ( я подумал что она есть в подключаемых библиотеках).
После исправления к тексту более близкому к книге ругается
alexemik@comp Work $ gcc server.c
server.c: In function ‘main’:
server.c:36:10: error: ‘serv_addr’ undeclared (first use in this function); did you mean ‘s6_addr’?
  memset(&serv_addr,0, sizeof(serv_addr));
          ^~~~~~~~~
          s6_addr
server.c:36:10: note: each undeclared identifier is reported only once for each function it appears in
alexemik@comp Work $

Оффлайн trs

  • Участник
  • *
  • Сообщений: 287
Да. Я не описал serv_addr.
НО. Эта структура не описана в исходниках данной программы
Существуют типы данных (int, float, struct some). В реальной жизни это, например, коты вообще (в смысле - не собаки).
Существуют экземпляры этих типов данных (переменные). В реальной жизни это конкретный кот Васька, который съел сметану.
// Объявление (forward declaration) типа данных - структуры с именем serv_addr.
struct serv_addr;

// Определение экземпляра данных.
// Типом является struct sockaddr_in, он определён в заголовках подключаемых библиотек
// serv_addr - имя экземпляра (переменной).
struct sockaddr_in serv_addr;

// Определение 2-х экземпляров структур sockaddr_in с именами serv_addr и clnt_addr;
struct sockaddr_in serv_addr, clnt_addr;
Первый вариант в исходнике, который Вы опубликовали.
Третий вариант в книге (подойдёт и второй, но останется ошибка с clnt_addr).

Так же посмотрите у себя и в книге (и у меня выше) строки с INADDR_ANY.

Оффлайн ALexeMiK

  • Участник
  • *
  • Сообщений: 132
    • Страница в ВК

Оффлайн ALexeMiK

  • Участник
  • *
  • Сообщений: 132
    • Страница в ВК
Из книги Робачевского успешно переписал исходники. Скомпилировались благополучно и клиент и сервер.
В книге написано:"клиент отправляет серверу сообщение, сервер передает его обратно, а клиент, в свою очередь, выводит полученное сообщение на экран"
Запускаю сервер.  Затем  клиент, передав ему свой адрес 127.0.0.1
И ничего не происходит. почему  не выводится hello world?
Привожу текст сервера

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PORTNUM 1500
 int nport;

 struct hostent *hp;
 
int main(argc, argv)

int argc;
char *argv[];
{
 int s, ns;
 int pid;
 char buf[80], hname[80];
/*Преобразуем порядок следования байтов к сетевому формату*/
  nport = PORTNUM;
  nport = htons((u_short)nport);
/*Создадим сокет использующий протокол TCP*/
  if ((s=socket(AF_INET, SOCK_STREAM, 0))==-1)
 {
        perror("Ошибка вызова socket()");
        exit(1);
 }
//Зададим адрес коммуникационного узла
 struct sockaddr_in serv_addr;
 struct sockaddr_in clnt_addr;
 memset(&serv_addr,0, sizeof(serv_addr));
 serv_addr.sin_family = AF_INET;
 serv_addr.sin_addr.s_addr = INADDR_ANY;
 serv_addr.sin_port = nport ;
//Свяжем сокет с этим адресом
if(bind(s,(struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1)
 {
        perror("Ошибка вызова bind()");
        exit(1);
 }
//Выведем сообщение с указанием адреса сервера
 fprintf(stderr, "Сервер готов %s\n",inet_ntoa(serv_addr.sin_addr));

 if(listen(s,5)==-1)
 {
        perror("Ошибка вызова listen()");
        exit(1);     
 }

 while(1)
 {
   int addrlen;
   memset(&clnt_addr,0,sizeof(clnt_addr));
   addrlen=sizeof(clnt_addr);
   //Примем запрос
   if((ns=accept(s,(struct sockaddr *)&clnt_addr,&addrlen))==-1)
   {
        perror("Ошибка вызова accept()");
        exit(1);     
   }
//Выведем инфо о клиенте
   fprintf(stderr,"Клиент = %s\n",inet_ntoa(clnt_addr.sin_addr));
//Создадим процесс для работы с клиентом
   if((pid=fork())==-1)   
   {
        perror("Ошибка вызова fork()");
        exit(1);     
   }


   if(pid==0)
   {
       int nbytes;
       int fout;
       close(s);
       while ((nbytes = recv(ns,buf,sizeof(buf),0))!=0)
       {
         send(ns,buf,sizeof(buf),0);
       }
       close(ns);
       exit(0);
   }
  close(ns);
 }
 return 0;
}

//Клиент
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PORTNUM 1500



 
int main(argc, argv)

int argc;
char *argv[];

{
  int s;
  int pid;
  int i,j;
  struct sockaddr_in serv_addr;
  struct hostent *hp;
  char buf[80]="Hello, World";

  if((hp=gethostbyname(argv[1]))==0)
  {
     perror("Ошибка вызова gethostbyname()");
     exit(3);
  }

   bzero(&serv_addr, sizeof(serv_addr));
   bcopy(hp->h_addr, &serv_addr.sin_addr,hp->h_length);
   serv_addr.sin_family =  hp->h_addrtype;
   serv_addr.sin_port = htons(PORTNUM);
//создадим сокет
   if((s=socket(AF_INET, SOCK_STREAM, 0))==-1)
  {
     perror("Ошибка вызова socket()");
     exit(1);
  }
   fprintf(stderr, "Адрес клиента : %s\n", inet_ntoa(serv_addr.sin_addr));

//создадим виртуальный канал
    if(connect(s, (struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1)
  {
     perror("Ошибка вызова connect()");
     exit(1);
  }
//отправим серверу сообщение и получим его обратно

   send(s,buf,sizeof(buf),0);
   if (recv(s,buf,sizeof(buf),0) <0)
  {
     perror("Ошибка вызова recv()");
     exit(1);
  }

   printf("Получено от сервера: %s\n", buf);
   close(s);
   printf("Клиент завершил работу \n\n");









Оффлайн ALexeMiK

  • Участник
  • *
  • Сообщений: 132
    • Страница в ВК
Забыл сказать клиент пишет Ошибка сегментирования

Оффлайн Skull

  • Глобальный модератор
  • *****
  • Сообщений: 20 167
    • Домашняя страница
А не надо кусками из сомнительных источников копипастить.
Андрей Черепанов (cas@)

Оффлайн Skull

  • Глобальный модератор
  • *****
  • Сообщений: 20 167
    • Домашняя страница
Показывайте запуск и вывод.
Андрей Черепанов (cas@)

Оффлайн ALexeMiK

  • Участник
  • *
  • Сообщений: 132
    • Страница в ВК
После перезагрузки заработало.