2013-11-14 3 views
0

Я пытаюсь установить соединение между клиентом и сервером, и когда он будет успешно, будет отображаться экран меню, предлагающий пользователю, хочет ли он 1) ввести сообщение 2) выйти из программы ,программирование сокетов получение ввода

проблемы я сталкиваюсь, когда я ключ в одном, он будет возвращать мне результат, показанный ниже

Client выхода (Это будет просто держать возвращение «Я получил свой Сообщ всякий раз, когда я вхожу в„-“, не имея пользователю вводить сообщение первым, пока не нажать Ctrl + C ")

Main Menu 
     ---------------------- 
1. option 1 
2. option 2 
Enter your choice1 
Please enter the message: I got your msg 
Main Menu 
     ---------------------- 
1. option 1 
2. option 2 
Enter your choice1 
Please enter the message: I got your msg 
Main Menu 
     ---------------------- 
    1. option 1 
    2. option 2 
    Enter your choice1 
    Please enter the message: I got your msg 

Сервер

Here is the msg: 

    Here is the msg: 

    Here is the msg: 

То, что я в настоящее время.

server.c

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

void doPrcoessing(int sock) { 
int n; 
char buffer[256]; 
bzero(buffer,256); 
n =read(sock,buffer,255); 

if(n < 0) { 
    perror("Error from reading socket"); 
    exit(1); 
} 

    printf("Here is the msg: %s\n",buffer); 
    n=write(sock,"I got your msg",18); 

if(n<0) { 
    perror("Error writing to socket"); 
    exit(1); 
} 
} 

int main(int argc, char *argv[]) 
{ 
    int sockfd,pid,newsockfd,portno,clientn; 
    struct sockaddr_in serv_addr,cli_addr; 
    char buffer[256]; 
    bool connected; 
    int n; 

    /*call socket() function*/ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(sockfd < 0) 
    { 
    perror("Error opening socket"); 
    exit(1); 
    } 
    // printf("socket retrieve success\n"); 

    /*Initialize socket structure*/ 

    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); 

    /*bind the host address using bind() call*/ 
    if(bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) { 
    perror("Error on binding!"); 
     exit(1); 
    } 
    int yes =1; 
    if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes, sizeof(yes)) == -1) { 
    perror("setsockopt"); 
    exit(1); 
    } 
    /*start listening for clients, will go into sleep mode and wait for incoming  connection*/ 
    listen(sockfd,5); 
clientn = sizeof(cli_addr);  
while(connected == false) { 
    newsockfd = accept(sockfd,(struct sockaddr*)&cli_addr,&clientn); 

    if(newsockfd < 0) { 
     perror("Error on accept!"); 
     exit(1); 
     } 

    /*Create chlid process*/ 
    pid =fork(); 
    if(pid < 0) 
    { 
     perror("Error on fork!"); 
     exit(1); 
    } 
    if(pid == 0) 
    { 
     /*Client process*/ 
     close(sockfd); 
     doPrcoessing(newsockfd); 
     return 0; 
    } 
    else 
    { 
     close(newsockfd); 
    } 
} 
return 0; 

}

client.c

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

void print(void); 

int sockfd, portno, n; 
struct sockaddr_in serv_addr; 
struct hostent *server; 
bool loop = false; 
char options[100]; 
char buffer[256]; 

int main(int argc, char *argv[]) 
{ 
while(loop==false) { 
    if (argc < 3) { 
     fprintf(stderr,"usage %s hostname port\n", argv[0]); 
     exit(0); 
    } 
    portno = atoi(argv[2]); 
/* Create a socket point */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) { 
     perror("ERROR opening socket"); 
     exit(1); 
    } 
server = gethostbyname(argv[1]); 
if (server == NULL) { 
     fprintf(stderr,"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); 

/* connect to the server */ 
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) { 
     perror("Error connecting"); 
     exit(1); 
} 

int choice; 
//print(); 
    if(choice !=2) { 
     printf("Main Menu"); 
     printf("\n\t----------------------"); 
     printf("\n 1. option 1"); 
     printf("\n 2. option 2"); 
     printf("\n Enter your choice"); 
     scanf("%d",&choice); 
     switch(choice) { 
     case 1: print(); 
      break; 
     case 2: exit(0); 
      break; 
     default: printf("Invalid choice!\n"); 
      break; 

     } 
    } 
} 
close(sockfd); 
    return 0; 
} 

void print(void) { 
/*ask for a message from the user, this message will be read by server */ 
printf("Please enter the message: "); 
     bzero(buffer,256); 
      fgets(buffer,255,stdin); 
     /* Send message to the server */ 
      n = write(sockfd,buffer,strlen(buffer)); 
     if (n < 0) { 
       perror("ERROR writing to socket"); 
       exit(1); 
      } 

     /* read server response */ 
      bzero(buffer,256); 
      n = read(sockfd,buffer,255); 
      if (n < 0) { 
       perror("ERROR reading from socket"); 
       exit(1); 
      } 

     printf("%s\n",buffer); 
} 
+1

Тесно читать человеко-страницы для чтения ' '/' write' и узнайте, что, по крайней мере, для сокетов эти две функции не обязательно читают/записывают столько байтов, сколько им было сказано, но мало. Таким образом, цикл таких звонков, подсчитанных до тех пор, пока все данные не были получены/отправлены, является хорошей идеей, не говоря уже о существенной необходимости. – alk

+0

OT: Также 'read' /' write' return 'ssize_t' не' int'. – alk

+0

спасибо за ваш совет @alk – user3429531

ответ

1

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

scanf("%d " ...) 
+0

благодарит за вашу помощь – user3429531

2

Причина, почему fgets() не удается прочитать буфер от входа, что ваш scanf оставил символ новой строки в буфере ввода.

Так что ваш fgets вернется вскоре после его вызова.

кода в client.c должна быть изменена, как показано ниже:

<code...> 
printf("Please enter the message: \n"); 
fflush(stdout); 
bzero(buffer,256); 
read(STDIN_FILENO, buffer, sizeof(buffer)); 
/* Send message to the server */ 
n = write(sockfd,buffer,strlen(buffer)); 
</code...> 

также коды в server.c должны быть изменены, как показано ниже:

<code...> 
scanf("%d ", &choice); 
</code...> 
Смежные вопросы