2017-04-25 3 views
1

今日の私の質問は、ソケットプログラミングに関するものです。私は、クライアントとサーバーを作成するプログラムで作業しています。クライアントは、指定されたコマンドを使用して、サーバーデータベース内のレコードと対話します。私はソケットプログラミングには非常に新しいので、サーバーとクライアントを接続して相互作用させるための初期コードをいくつか与えました。つまり、「停止」コマンドが出されるまで、別のメッセージを受信して​​送信するためには、コードのどの部分を反復する必要があるのか​​よく分かりません。それまでは、ユーザーが引き続きサーバーにメッセージを送信できるようにしたいと考えています。ソケットプログラムによるシーケンシャルユーザー入力の受け入れ

(関連する)サーバコード:

void error(char *msg) 
{ 
    perror(msg); 
    exit(1); 
}  
int main() { 
    int num = 1; 
    int del; 
    int sockfd, newsockfd, portno; 
    socklen_t clilen; 
    char buffer[256]; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 


    /*STEP 1*********************************************/ 

    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    /*Make sure opening was successful*/ 
    if (sockfd < 0) 
     error("ERROR opening socket"); 

    /*STEP 2******************************************** 
     0 out the server address*/ 

    memset((char *) &serv_addr, 0, sizeof(serv_addr)); 

    /*convert argument to int*/ 
    portno = PORTNO; 

    /*this is always the same for this type of connection*/ 
    serv_addr.sin_family = AF_INET; 

    /*INADDR_ANY is a macro that will find the current machine IP*/   
    serv_addr.sin_addr.s_addr = INADDR_ANY; 

    /*make sure byte order is correct 
     may be a no-op, but better safe than sorry*/ 
    serv_addr.sin_port = htons(portno); 



    /*STEP 3********************************************/ 
    if (bind(sockfd, (struct sockaddr *) &serv_addr, 
       sizeof(serv_addr)) < 0) { 
     error("ERROR on binding"); 
    } 



    /*STEP 4******************************************** 
        Open server up for listening, if you don't listen 
        you won't hear*/ 

    listen(sockfd,5); 


    /*STEP 5******************************************/ 

    clilen = sizeof(cli_addr); 

    /*Accept blocks until a connection with 
     a client is made. Returns a new socket 
     to communicate with the new connection. 
     Also receives address data about client*/ 



    /*Communicate************************************/ 

    char *array[20]; 
    do { 
     newsockfd = accept(sockfd, 
       (struct sockaddr *) &cli_addr, 
       &clilen); 

     if (newsockfd < 0) 
      error("ERROR on accept"); 

     memset(buffer, 0, 256); 

     printf("%s", "Enter Message:"); 
     n = read(newsockfd,buffer,255); 
     printf("I read %d\n",n); 

     if (n < 0) error("ERROR reading from socket"); 
     printf("Here is the message: %s",buffer); 

     n = write(newsockfd,"I got your message",18); 
     if (n < 0) error("ERROR writing to socket"); 

     int i = 0; 
     char *p = strtok(buffer, " "); 

     while (p != NULL) 
     { 
      array[i++] = p; 
      p = strtok (NULL, " "); 
     } 
     if (strcmp(array[0], "put") == 0) { 
      insert(&front, array); 
      puts("PUT COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "lname") == 0) { 
      puts("GET LNAME COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "fname") == 0) { 
      puts("GET FNAME COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "SID") == 0) { 
      puts("GET SID COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "GPA") == 0) { 
      puts("GET GPA COMMAND"); 
     } else if (strcmp(array[0], "delete") == 0 && strcmp(array[1], "SID") == 0) { 
      puts("DELETE COMMAND"); 
     } else { 
      printf("%s\n", "Not a valid command."); 
     } 
    } while (strcmp(array[0], "stop") != 0); 

    return 0; 
} 

(関連)クライアントコード:

#define PORTNO 20321 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <unistd.h> 


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

int main(int argc, char *argv[]) 
{ 
    /*set up ints for socket file descriptor 
     port number and return of read/write*/ 
    int sockfd, portno, n; 
    int i; 

    /*structure for server info*/ 
    struct sockaddr_in serv_addr; 

    /*used to hold the return of the function 
     that finds our server address, will 
     be copied into serv_addr*/ 
    struct hostent *server; 


    /*for our message*/ 
    char buffer[256]; 

    /*make sure usage is correct*/ 
    if (argc < 2) { 
     fprintf(stderr,"usage %s hostname\n", argv[0]); 
     exit(0); 
    } 

    /*convert our port number*/ 
    portno = PORTNO; 

    /*create the socket*/ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    /*make sure it was made*/ 
    if (sockfd < 0) 
     error("ERROR opening socket"); 

    /*gethostbyname takes our host domain name and 
     resolves it to an address, there is a similar 
     function, gethostbyaddr that takes an address 
     and returns the same struct, struct hostent*/ 
    server = gethostbyname(argv[1]); 

    /*make sure the host exists*/ 
    if (server == NULL) { 
     fprintf(stderr,"ERROR, no such host\n"); 
     exit(0); 
    } 

    /*0 out the server address stuct and set members*/ 
    memset((char *) &serv_addr, 0, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 

    /*copy the data returned from gethostbyname 
     into the server address struct*/ 
    memcpy((char *)server->h_addr_list, 
      (char *)&serv_addr.sin_addr.s_addr, 
      server->h_length); 
    serv_addr.sin_port = htons(portno); 

    /*Request a connection to the server through the socket we set up 
     make sure it connected, this function will also do the binding 
     of our socket and server info*/ 
    if (connect(sockfd,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0) { 
     error("ERROR connecting"); 
    } 

    for (i = 0; i < 3; i++) { 
     printf("Choose an operation: \n 1. put ln,fn,mi,SID,GPA\n 2. get lname\n 3. get fname\n 4. get SID\n 5. get GPA\n 6. delete (SID)\n 7. stop\nChoice: "); 
     /*Retrieve a message to send from the user*/ 

     memset(buffer, 0, 256); 
     fgets(buffer,255,stdin); 

     /*send the message to the socket*/ 
     printf("length is %d\n", (int)strlen(buffer)); 
     n = write(sockfd,buffer,strlen(buffer)); 
     if (n < 0) 
      error("ERROR writing to socket"); 
     memset(buffer, 0, 256); 

     /*await an incoming message, read stops all process*/ 
     n = read(sockfd,buffer,255); 
     if (n < 0) 
      error("ERROR reading from socket"); 
     printf("%s\n",buffer); 
     return 0; 
    } 
} 

私のサーバーは、私は私のクライアントプログラムを再起動し、別のものを送ることができるよう、正しくメッセージを待っているように見えますサーバーが待機している間、通常どおり受信されます。しかし、それが立つように、それは別のメッセージを求めますが、最初のメッセージのように正しく送受信されません。今のところ、テストとして3回ループするように設定しています。この読み書きループをサーバーに正しく作成するにはどうすればよいですか?

答えて

0

一度に1つの接続しか持たず、テストされていないバージョンのyou whileループが動作すると仮定します。

while (true) 
{ 
    newsockfd = accept(sockfd, 
      (struct sockaddr *) &cli_addr, 
      &clilen); 

    if (newsockfd < 0) 
     error("ERROR on accept"); 

    while (true) 
    { 
     memset(buffer, 0, 256); 

     printf("%s", "Enter Message:"); 
     n = read(newsockfd,buffer,255); 
     printf("I read %d\n",n); 

     if (n < 0) error("ERROR reading from socket"); 
     printf("Here is the message: %s",buffer); 

     n = write(newsockfd,"I got your message",18); 
     if (n < 0) error("ERROR writing to socket"); 

     int i = 0; 
     char *p = strtok(buffer, " "); 

     while (p != NULL) 
     { 
      array[i++] = p; 
      p = strtok (NULL, " "); 
     } 
     if (strcmp(array[0], "put") == 0) { 
      insert(&front, array); 
      puts("PUT COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "lname") == 0) { 
      puts("GET LNAME COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "fname") == 0) { 
      puts("GET FNAME COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "SID") == 0) { 
      puts("GET SID COMMAND"); 
     } else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "GPA") == 0) { 
      puts("GET GPA COMMAND"); 
     } else if (strcmp(array[0], "delete") == 0 && strcmp(array[1], "SID") == 0) { 
      puts("DELETE COMMAND"); 
     } 
     // Checking for stop command here 
     else if (strcmp(array[0], "stop") ==0) 
     { 
      close(newsockfd); 
      break; 
     } 
     else { 
      printf("%s\n", "Not a valid command."); 
     } 
    } 
} 
関連する問題