2015-05-30 6 views
0

Я написал программу на основе сервера/клиента. Основная функция программы заключается в том, что клиент отправит символ, например, на сервер, сервер увеличит его и отправит обратно. Поэтому, если клиент отправит «a», он получит «b». Но когда клиент отправляет «q», сервер должен закрыть соединение. Программа делает то, что должна делать, но на стороне клиента дважды печатает «Ввести символ» и «Символ с сервера». Также отправка «q» закрывает соединение, но только если вы отправите его во второй раз.программирование сокетов в c unix

Вот стороне сервера код

void *client_thread(void *client_sockfd){ 
    int socket=*(int *)client_sockfd; 
    while(1){ 
     read(socket, &ch, 1); 
     if(ch=='q') 
     { 
      close(socket); 
     } 
     else 
     { 
      ch++; 
      write(socket, &ch, 1); 
     } 
    } 
    //close(socket); 
    printf("Connection closed with %d",socket);  

}//end fucntion 

стороне клиента код

while(1) 
{ 
    printf("Enter a character"); 
    scanf("%c",&ch); 
    write(sockfd, &ch, 1); 
    read(sockfd, &ch, 1); 
    printf("char from server = %c\n", ch); 

    // close(sockfd); 
    //exit(0); 
} 
if(ch=='q'){ 
    printf("Server closed the connection"); 
} 
+0

Возможно, вы захотите добавить код для проверки того, что чтение и запись на самом деле преуспели – mathematician1975

ответ

0

Client Side: Здесь две строки печатаются, потому что есть два входа один ваш персонаж и второй является enter или \n

Так используйте scanf("%c%c",&ch); на стороне клиента.

стороне сервера: И второе использование while((n = read(sockfd, &ch, 1))>0), чтобы остановить его автоматическое завершение соединения. Оператор read возвращает количество прочитанных байтов.

Поскольку значение, которое вы предоставляете, не стирается после получения приращения. Причина заключается в том:

  • Пусть ваш вклад a, то ответы сервера b к вам и как вы не проверить значение return из read в стороне сервера, поэтому он увеличивает ch каждый раз, когда и как она достигает q и розетка закрывается.
  • Когда сервер увеличивает значение, он также отправляет его клиенту, но поскольку клиент находится в режиме scanf, он не может получить вход до инструкции read, по этой причине вы не можете увидеть автоматическое значение приращения. И приращение настолько быстро, что до вашего следующего ввода сокет уже был завершен.
+0

Вот почему @AliRehman – Subinoy

+0

Спасибо большое. Теперь он работает отлично. Я также отредактировал цикл while на стороне клиента, пока (m> 0), где m имеет возвращаемое значение на стороне клиента. Это не делает ничего необычного, но скажите мне, хорошо ли это сделать. @Subinoy –

+0

Всегда используйте возвращаемые значения функций. Это хорошо для программы. :-) – Subinoy

1

зсапЕ читает один символ за один раз, поэтому при вводе символа и нажмите клавишу ввода, первый цикл будет читать символ, второй будет читать новую строку.

Вы можете использовать

scanf("%c%*c", &ch); 

, который считывает два символа, но сохраняет только первый один.

+0

, это работало не для печати дважды, а для закрытия соединения по случайному символу. –

+0

используйте этот 'while ((n = read (sockfd, & ch, 1))> 0)' вместо 'while (1)' @AliRehman – Subinoy

+0

, где именно я должен его использовать? –

0
printf("Enter a character"); 
scanf("%c",&ch); 

Вы на самом деле ввести два символа, по одному для каждого ключа нажать, второй из которых от Enter, и это символ новой строки, /n. Поэтому каждый выход из

printf("char from server = %c\n", ch); 

, вероятно:

char from server = 

Тогда есть пустая строка, то другой выход. Если вы сделали это вместо:

printf("char from server = %d\n", (int)ch); 
         // ^not %c 

Актерский к int не является действительно необходимым там, но подчеркивает идею; Теперь вы получите десятичную ASCII значение символа, а каждая вторая линия будет теперь:

char from server = 10 

Это символ новой строки. Для того, чтобы справиться с этой проблемой, которая до вас догнала бесчисленных C неофитов, see my answer here.

0

Ваша программа делает следующее ...

  1. распечатывает сообщение «Введите символ» и блоки ждут STDIN
  2. пользователя типы «а» и «\ п» - зсап() не возвращает управление до символа новой строки
  3. пишет «а», читает «B», «B» печатает, а затем подсказками «Введите символ»
  4. Scanf имеет характер уже (\ п), поэтому он немедленно возвращается
  5. Записывает '\ n', читает '\ n' + 1, печатает '\ n' + 1 и promp ts "Введите символ"
  6. Повторы с 1.

Именно поэтому вы видите «Введите символ» дважды.

Что касается необходимости отправить 'q' дважды, то ваш цикл сервера не выйдет, когда он получит 'q', он вызывает закрытие и продолжает чтение. После каждого чтения после этого произойдет сбой и немедленный возврат кода ошибки. Аналогично, ваш клиентский цикл не срабатывает.

Захват и проверка ваших возвращаемых значений. Кроме того, перейдите к отладчику - это ответит на многие из ваших вопросов о C, не дожидаясь ответа на вопросы.

Смежные вопросы