2013-03-23 1 views
0

클라이언트에서 서버로 옵션을 보내려고합니다. 서버는 몇 가지 비교를 수행하고 문자열을 클라이언트에 다시 보내야합니다. 클라이언트로부터 데이터를받을 수는 있지만 비교할 때 서버가 충돌합니다 ("오류 입력"으로 연결되어 연결을 종료 함). 누군가 내가 뭘 잘못하고 있다고 말할 수 있습니까?서버 C 프로그래밍에서 클라이언트가 보낸 데이터를 비교하는 방법

Incorrect Inputclose error: Bad file descriptor

Program exited with code 01.

서버 :

void 
result(int sockfd) 
{ 
    ssize_t  n; 
    char  buf[MAXLINE]; 
    int   temp; 
    time_t  ticks; 
again: 
    while ((n =read(sockfd, buf, MAXLINE)> 0)) 
    { 
    temp = rand() % 22; 
    if (buf=="A\n" || buf=="a\n") 
    { 
     snprintf(buf, sizeof(buf), "You option is number is -%i, time is %.24s\r\n", temp,ctime(&ticks)); 
     Writen(sockfd, buf, n); 
    } 
    if (buf=="B\n" || buf=="f\") 
    { 
     snprintf(buf, sizeof(buf), "You option is number is -%i, time is %.24s\r\n", temp,ctime(&ticks)); 
     Writen(sockfd, buf, n); 
    } 
    else 
    { 
     printf("Incorrect Input"); 
     Close(sockfd); 
    } 
    } 
    if (n < 0 && errno == EINTR) 
    goto again; 
    else if (n < 0) 
     err_sys("read error"); 
} 

int 
main(int argc, char **argv) 
{ 
    int   listenfd, connfd; 
    socklen_t  len; 
    struct sockaddr_in servaddr, cliaddr; 
    char   buff[MAXLINE]; 
     char   recvline[MAXLINE + 1]; 

    listenfd = Socket(AF_INET, SOCK_STREAM, 0); 
    bzero(&servaddr, sizeof(servaddr)); 
    servaddr.sin_family  = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/ 
    servaddr.sin_port  = htons(5678); 

    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); 
    Listen(listenfd, LISTENQ); 
    printf("EDMTS is running on 129.128.4.80, listening on port 5678\n"); 
    printf("\n"); 
    printf("Waiting for incoming connections...Press Ctrl+C to end server\n"); 

    for (; ;) 
     { 
     len = sizeof(cliaddr); 
     connfd = Accept(listenfd, (SA *) &cliaddr, &len); 

     /*Client connects to server*/ 
     printf("\n"); 
     printf("Connection from %s, port %d\n", 
       Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), 
       ntohs(cliaddr.sin_port)); 

       result(connfd); 
       Close(connfd); 
     printf("Conexion cerrada...Esperando siguiente cliente\n"); 
     } 
} 

클라이언트

void 
get_temp(FILE *fp, int sock) 
{ 
    char sendline[MAXLINE], recvline[MAXLINE]; 

    while (Fgets(sendline, MAXLINE, fp) != NULL) { 

     Writen(sock, sendline, strlen(sendline)); 

     if (Readline(sock, recvline, MAXLINE) == 0) 
      err_quit("Server Terminated Prematurely"); 

     Fputs(recvline, stdout); 
    } 
} 


int 
main(int argc, char **argv) 
{ 
    int     sockfd, n; 
    socklen_t   len; 
    char    recvline[MAXLINE + 1]; 
    struct sockaddr_in servaddr, cliaddr; 
    char scale[2]; 

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
     err_sys("socket error"); 

    bzero(&servaddr, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_port = htons(atoi(argv[2])); 
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) 
     err_quit("inet_pton error for %s", argv[1]); 

    printf("Connect...\n"); 
    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) 
     err_sys("connect error"); 

    len = sizeof(cliaddr); 
    Getsockname(sockfd, (SA *) &cliaddr, &len); 
    printf("Local Address is: %s\n", 
      Sock_ntop((SA *) &cliaddr, sizeof(cliaddr))); 

    printf("Enter option A or B): "); 
    get_temp(stdin, sockfd); 

    exit(0); 
} 

내 변수를 찾을 수있는 디버거를 실행하면, 내가 찾을 :

Breakpoint 1, result (sockfd=7) at servertest.c:236 236
printf("Random es %i\n",temp); (gdb) p buf $1 = "A\n", '\0' , "\203\217��", '\0' , "h\206��h\206��\204\210������#���\000\000\000\000�\206����߷\020\207��#���", '\0' , "������������\000\000\000\000\000\000\000\000�\017��", '\0' , "h\206��", '\0' , "\001\000\000\000\000\000\000\000�\207��", '\0' , "����\t\000\000\000#���\030���\000\000\000\000h\206��\003", '\0' , "\n\000\000\000g\206��", '\0' , " "... (gdb) p temp $2 = 17

매우

감사합니다

답변

1

첫째, 당신이 (당신이 포인터 adresses를 비교합니다 ==를 사용하여 C 문자열을 비교하고, 버피의 주소 수 없습니다 [0] 문자열을 비교하려면 strncmp()

Close()를 호출하면 read() 함수가 다시 호출되므로 충돌이 발생합니다. 소켓 파일 디스크립터. 크래시를 제거하려면 break; 닫기() 후 (다음) :

else 
{ 
    printf("Incorrect Input"); 
    Close(sockfd); 
    break; 
} 
0

또한 소켓을 두 번 닫고 있습니다. 여기 첫째 : 그럼 여기

// void result(int sockfd) 
else 
{ 
    printf("Incorrect Input"); 
    Close(sockfd); // <<< 
} 

: 모든

// int main(int argc, char **argv) 
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), 
ntohs(cliaddr.sin_port)); 

result(connfd); 
Close(connfd); // <<< 
printf("Conexion cerrada...Esperando siguiente cliente\n"); 
관련 문제