2012-09-18 3 views
2

현재 서버에서 여러 값을 읽는 데 문제가 있습니다. 이것은 클라이언트/서버 프로그램입니다. 사용자는 클라이언트의 국가 이름을 입력해야하며 서버는 해당 국가의 자본과 통화를 반환합니다. 첫 번째 입력 예 China를 입력했는데 서버가 올바른 데이터를 반환합니다. 그러나 싱가포르의 후속 값을 입력 할 때. 그들은 아무것도 돌려 보내지 않았다. 코드가 잘못된 점을 알려주십시오. 서버는 입력 된 국가의 자본과 통화를 반환해야합니다.서버에서 데이터를 읽는 중 문제가 발생했습니다.

다음은 서버 및 클라이언트에 대한 코드입니다. 죄송합니다, 그들은 조금 긴하지만 난 내가

server.c

#include <stdlib.h> 
#include <stdio.h> 
#include <signal.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/un.h>  /* for sockaddr_un struct */ 
#include <string.h> 
#include "country.h" 
#define DEFAULT_PROTOCOL 0 

/* POSIX renames "Unix domain" as "local IPC." 
    Not all systems define AF_LOCAL and PF_LOCAL (yet). */ 
#ifndef AF_LOCAL 
#define AF_LOCAL AF_UNIX 
#endif 
#ifndef PF_LOCAL 
#define PF_LOCAL PF_UNIX 
#endif 


/****************************************************************/ 
int main () 
    { 


    int serverFd, clientFd, serverLen, clientLen; 
    struct sockaddr_un serverAddress;/* Server address */ 
    struct sockaddr_un clientAddress; /* Client address */ 
    struct sockaddr* serverSockAddrPtr; /* Ptr to server address */ 
    struct sockaddr* clientSockAddrPtr; /* Ptr to client address */ 

    /* Ignore death-of-child signals to prevent zombies */ 
    signal (SIGCHLD, SIG_IGN); 

    serverSockAddrPtr = (struct sockaddr*) &serverAddress; 
    serverLen = sizeof (serverAddress); 

    clientSockAddrPtr = (struct sockaddr*) &clientAddress; 
    clientLen = sizeof (clientAddress); 

    /* Create a socket, bidirectional, default protocol */ 
    serverFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL); 
    serverAddress.sun_family = AF_LOCAL; /* Set domain type */ 
    strcpy (serverAddress.sun_path, "country"); /* Set name */ 

    unlink ("country"); /* Remove file if it already exists */ 

    bind (serverFd, serverSockAddrPtr, serverLen); /* Create file */ 
    listen (serverFd, 5); /* Maximum pending connection length */ 


    printf ("%s \n", "Starting Country Server"); 
    printf ("%s \n", " "); 

    while (1) /* Loop forever */ 
     { 
     /* Accept a client connection */ 
     clientFd = accept (serverFd, clientSockAddrPtr, &clientLen); 

     if (fork() == 0) /* Create child to send recipe */ 
      { 
      //writeCountryData (clientFd); /* Send the recipe */ 
     while(1) 
     { 
     readCountry (clientFd); 
      close (clientFd); /* Close the socket */ 

      exit (/* EXIT_SUCCESS */ 0); /* Terminate */ 
      } 
     else 
      close (clientFd); /* Close the client descriptor */ 
     } 

    return 0; 
    } 

    /****************************************************************/ 

readCountry (int fd) 
{ 

    readData(); 
    char capital[100]="", currencyCode[100]="", *p; 
     char userInput[200]; 

     read(fd, userInput, 200); 

    if ((p = strchr(userInput, '\n')) != NULL) /* to remove the [enter] from userinput */ 
     *p = '\0'; 

    strcat(capital,userInput) ; 
    strcat(capital," Capital  : ") ; 
    strcat(capital,getCapital (userInput)); 

    write (fd, capital, strlen (capital) + 1); 
    strcat(currencyCode,userInput) ; 
    strcat(currencyCode," Currency Code  : ") ; 
    strcat(currencyCode,getCurrencyCode (userInput)); 
    write (fd, currencyCode, strlen (currencyCode) + 1); 


} 

readLine (int fd, char* str) 
{ 
    int n; 
    do /* Read characters until NULL or end-of-input */ 
    { 
    // ssize_t read (int fd, void *buf, size_t count); 
    // if successful, read will: 
    // a) stores data read into 'buf', and 
    // b) returns the no. of bytes read 
    // read returns zero if it reaches end-of-input 
     n = read (fd, str, 1); /* Read one character */ 
    } 
    while (n > 0 && *str++ != 0); 
    return (n > 0); /* Return false if end-of-input */ 
} 





} 

이 client.c

#include <stdlib.h> 
#include <stdio.h> 
#include <signal.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/un.h>   /* for sockaddr_un struct*/ 

#define DEFAULT_PROTOCOL 0 

/* POSIX renames "Unix domain" as "local IPC." 
    Not all systems define AF_LOCAL and PF_LOCAL (yet). */ 
#ifndef AF_LOCAL 
#define AF_LOCAL AF_UNIX 
#endif 
#ifndef PF_LOCAL 
#define PF_LOCAL PF_UNIX 
#endif 

/****************************************************************/ 
main () 
{ 
    int clientFd, serverLen, result; 
    struct sockaddr_un serverAddress; 
    struct sockaddr* serverSockAddrPtr; 
    serverSockAddrPtr = (struct sockaddr*) &serverAddress; 
    serverLen = sizeof (serverAddress); 

    /* Create a socket, bidirectional, default protocol */ 
    clientFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL); 
    serverAddress.sun_family = AF_LOCAL; /* Server domain */ 
    strcpy (serverAddress.sun_path, "country"); /* Server name */ 
    do /* Loop until a connection is made with the server */ 
    { 
     result = connect (clientFd, serverSockAddrPtr, serverLen); 
     if (result == -1) sleep (1); /* Wait and then try again */ 
    } 
    while (result == -1); 

    while (1) 
    { 
    char country[300]; 
    printf("To end program, type 'end' \n"); 
    printf("Please enter country name >"); 
    fgets(country,sizeof(country),stdin); 
    if (strcmp(country,"end\n") == 0) 
    { 
     printf("Thank you for using country services\n"); 
     break; 

    } 
    else 
    write(clientFd,country,strlen(country)); 
    readCountry(clientFd); 
    close(clientFd); 


    } 


    /* Read the recipe */ 

    /* Close the socket */ 
    exit (/* EXIT_SUCCESS */ 0); /* Done */ 




} 
/**************************************************************/ 

readCountry(int fd) 
{ 
    char str[300]; 

    while (readLine (fd, str)) /* Read lines until end-of-input */ 
    printf ("%s\n", str); /* Echo line from socket */ 
} 

/**************************************************************/ 

/* Read a single NULL-terminated line */ 
readLine (int fd, char* str) 
{ 
    int n; 
    do /* Read characters until NULL or end-of-input */ 
    { 
    // ssize_t read (int fd, void *buf, size_t count); 
    // if successful, read will: 
    // a) stores data read into 'buf', and 
    // b) returns the no. of bytes read 
    // read returns zero if it reaches end-of-input 
     n = read (fd, str, 1); /* Read one character */ 
    } 
    while (n > 0 && *str++ != 0); 
    return (n > 0); /* Return false if end-of-input */ 
} 

    writeUserInput(int fd) 
    { 

    char text[20]; 
    printf("To end program, type 'end' \n\n\n"); 
    printf("Please enter Country > "); 
    fgets (text, sizeof(text), stdin); 



    write (fd, text, strlen (text) + 1); 

    } 

답변

3

서버 댓글 당신이 필요로하는 전체 그림 너희들에게 당신에게 자사의 더 나은 것 같아요 매번 소켓 크기를 설정하십시오.

/* Accept a client connection */ 
    clientLen = sizeof (clientAddress); // this line was missing 
    lientFd = accept (serverFd, clientSockAddrPtr, &clientLen); 

사실 변수를 사용하는 곳에서 변수를 선언하면 RAII가이 문제를 제거합니다.

방금 ​​C와 C++가 아니라는 것을 알았으므로 RAII 주석을 잊어 버렸지 만 크기를 설정해야합니다.

당신은에 sizeof 연산자를 사용한다 :

char userInput[200]; 

    read(fd, userInput, 200); 

그리고 함수 역시이 사용되어야한다 :

char capital[100]="", currencyCode[100]="", *p; 
    //... 
strcat(capital,userInput) ; 
strcat(capital," Capital  : ") ; 

및 currencyCode에 대해 동일합니다.

실제로 fork()가 필요하지는 않지만 하나의 스레드/프로세스에서 모두 수행 할 수 있습니다.

Client Comments 

코드는 다음과 같습니다

connect to server 

    while (true) 
    get input 
    send request 
    read reply 
    close connection to server 
+0

덕분에 당신이 중대하다 –

관련 문제