C: программа сокет сервер / клиент - ошибка подключения клиента - PullRequest
0 голосов
/ 12 октября 2018

Я новичок в работе с сетями и пытаюсь создать простую клиентскую программу с серверным сокетом на C, где аргументы определяют, должна ли программа работать как клиент или сервер.Я сделал это, используя простые операторы if (если задан флаг, запускается как сервер, иначе запускается как клиент), но я не уверен, как это проверить.Я запускаю свой код с аргументом «быть сервером в одном терминале» (например, на локальном хосте и с номером порта 3000), открываю другой терминал и запускаю код с аргументом «клиент» (также на локальном хосте и на том же порту).

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

(Я получил код поведения сервера и клиента с одного из многих веб-сайтов в сети, но они разделяют client.c и server.c, тогда как я хочу объединить оба водна программа .c)

Вот мой код ниже, ошибка вызывается

if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
       error("ERROR connecting");

в клиентской части кода.

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

void error(char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
 int sockfd, newsockfd, portno, clilen;
 char buffer[256];
 struct sockaddr_in serv_addr, cli_addr;
 int n, i, server = 0;  // 1 = server, 0 = client

 // check if server or client
 for (i = 0; i<argc; i++) {
   if (strcmp(argv[i], "-l") == 0)
      server = 1;
 }

 // client
 if (server == 0) {
   struct hostent *server;

   if (argc < 3) {
      fprintf(stderr,"usage %s hostname port\n", argv[0]);
      exit(0);
   }
   portno = atoi(argv[2]);
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   if (sockfd < 0)
       error("ERROR opening socket");
   server = gethostbyname(argv[1]);
   if (server == NULL) {
       fprintf(stderr,"FOUR*** ERROR, no such host\n");
       exit(0);
   }
   bzero((char *) &serv_addr, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   bcopy((char *)server->h_addr,
        (char *)&serv_addr.sin_addr.s_addr,
        server->h_length);
   serv_addr.sin_port = htons(portno);
   if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
       error("ERROR connecting");
   printf("Please enter the message: ");
   bzero(buffer,256);
   fgets(buffer,255,stdin);
   n = write(sockfd,buffer,strlen(buffer));
   if (n < 0)
        error("ERROR writing to socket");
   bzero(buffer,256);
   n = read(sockfd,buffer,255);
   if (n < 0)
        error("ERROR reading from socket");
   printf("%s\n",buffer);
   return 0;
 }

 // server
 if (server == 1) {

   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   if (sockfd < 0)
      error("ERROR opening socket");
   bzero((char *) &serv_addr, sizeof(serv_addr));
   portno = atoi(argv[1]);
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;
   serv_addr.sin_port = htons(portno);
   if (bind(sockfd, (struct sockaddr *) &serv_addr,
            sizeof(serv_addr)) < 0)
            error("ERROR on binding");
   listen(sockfd,5);
   clilen = sizeof(cli_addr);
   newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
   if (newsockfd < 0)
        error("ERROR on accept");
   bzero(buffer,256);
   n = read(newsockfd,buffer,255);
   if (n < 0) error("ERROR reading from socket");
   printf("Here is the message: %s\n",buffer);
   n = write(newsockfd,"I got your message",18);
   if (n < 0) error("ERROR writing to socket");
   return 0;
 }
}

Вот точный вывод ошибки:

В одном окне терминала я сначала запускаю программу как сервер:

$ ./socketz -l localhost 2003

Затем в другом окне терминала,Я запускаю программу как клиент:

$ ./socketz localhost 2003
ERROR connecting: Connection refused

1 Ответ

0 голосов
/ 12 октября 2018

Причина, по которой вы не можете подключиться, заключается в том, что ваш серверный процесс не прослушивает порт 2003. В частности, в этой строке:

 serv_addr.sin_port = htons(portno);

Значение portno равно нулю, что вызываетзначение serv_addr.sin_port также должно быть равно нулю, что accept() интерпретирует как означающее, что он должен просто выбрать доступный TCP-порт для привязки.

Корень проблемы здесь:

 portno = atoi(argv[1]);

... эта строка присваивает значение portno на основе первого аргумента, который вы ввели при запуске программы, но вы ввели это:

 ./a.out -l localhost 2003

Таким образом, первый аргумент - "-l", который не является числом, поэтому atoi() вернет 0. Я думаю, что вы хотели portno = atoi(argv[3]);.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...