0

クライアントとサーバー間の接続を確立しようとしていますが、成功すると、ユーザーに 1) メッセージを入力する 2) プログラムを終了するかどうかを尋ねるメニュー画面が表示されます。

私が直面した問題は、キーを入力したときでした。以下に示す出力が返されます

クライアント出力 (ctrl+c を押すまで、最初にユーザーにメッセージを入力してもらうことなく、'1' を入力するたびにメッセージを受け取りました) を返し続けます)

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

2 に答える 2

1

scanf does not consume the newline that the user hits after making a selection. But the fgets immediately does, and nothing else. The correct solution is to stop using scanf (that's the correct solution for any program that uses scanf, IMO). But it's probably simpler to add a space to the format string:

scanf( "%d " ... )
于 2013-11-14T15:00:05.090 に答える