2013-03-22 3 views
0

Мне нужно отправить сообщение клиенту, а затем клиент должен ответить опцией. Я получаю до тех пор, пока клиент и сервер не подключатся, но обе программы заканчиваются на «Segmentation Fault». Кто-нибудь знает, что означает эта ошибка? Может кто-то дать идею о том, как создать код, который заставит клиента и сервер взаимодействовать. После получения опции, выбранной клиентом, серверу необходимо проанализировать его и снова отправить результат клиенту.Ошибка сегментации при попытке отправить сообщение клиенту с сервера

Мои коды:

Сервер

int 
main(int argc, char **argv) 
{ 
    int     listenfd, connfd; 
    socklen_t   len; 
    struct sockaddr_in servaddr, cliaddr; 
    char    buff[MAXLINE]; 
    time_t    ticks; 
    char    message[MAXLINE]="This is the server"; 
    char    temp_scale[2]; 
    char    recvdata[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(5555); 

    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); 
    Listen(listenfd, LISTENQ); 

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

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


     snprintf(message, sizeof(message), "%s\r\n"); 
      Writen(connfd, message, strlen(message)); 
      while ((n = read(connfd, recvdata, MAXLINE)) > 0) 
      { 
      recvdata[n] = 0; /* null terminate*/ 
      if (fputs(recvdata, stdout) == EOF) 
       err_sys("fputs error"); 
      } 
      if (n < 0) 
      err_sys("read error"); 

      Close(connfd); 
    } 
} 

Клиентские

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

    /*if (argc != 2) 
     err_quit("usage: a.out <IPaddress>");*/ 

    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])); /*port passed through command line*/ 
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) /*The client translates the server address, passed on the command line*/ 
     err_quit("inet_pton error for %s", argv[1]); 


    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("Iniciando read...\n"); 
    while ((rd = read(sockfd, recvline, MAXLINE)) > 0) 
    { 
     recvline[rd] = 0; /* null terminate*/ 
     if (fputs(recvline, stdout) == EOF) 
      err_sys("fputs error"); 
    } 
    if (rd < 0) 
    err_sys("read error"); 

    printf("Enter option 'A' or 'B'"); 
    send_scale(sockfd); 

    exit(0); 
} 

Благодаря

+0

Ошибка сегментации означает, что у вас есть доступ к запрещенной памяти, т. Е. У вас есть ошибка, связанная с недопустимым доступом или указателем или ограниченным доступом к границам. – Lundin

+0

Любая конкретная причина, по которой некоторые буферы имеют длину MAXLINE, но некоторые имеют MAXLINE + 1? Без понимания кода это пахнет как ошибка. – Lundin

+0

Спасибо, так что я могу знать, как это исправить? Я использую те же функции в клиенте и сервере, это ли проблема? – netfreak

ответ

2

Ваш сервер, вероятно, разломообразования из-за этого:

snprintf(message, sizeof(message), "%s\r\n"); // <== no parameters 

Это утончаются неправильно. Вызов snprintf() имеет спецификатор формата, который ожидает char * в строку с нулевым завершением, и вы ничего не передаете. Поэтому он захватывает случайное значение из стека, обрабатывает его как указатель и разыскивает его, пытаясь выполнить отформатированный запрос.

Не зная деталей API, которые вы используете (это явно не стандартные сокеты BSD только по именам), не так много.

+0

Спасибо WhozCraig! Это было то, что у меня есть строка и работает! Теперь я составлю часть чтения, я отправляю сообщение с сервера клиенту, но клиент не получает его. И клиент и сервер остаются в блокировке чтения (сервер ожидает ответа от клиента).Вы знаете, что это происходит? – netfreak

+0

@netfreak Я этого не делаю, но я немного погляжу и посмотрю, выскочит ли он ко мне. Я не парень-сокет, но на этом сайте есть много, поэтому, возможно, один будет прослушивать. – WhozCraig

2

запустить свой код в отладчике (например gdb ./a.out) и выяснить, в кратчайшие сроки ,

0

Я не знаю, если это может помочь, но в C нулевое окончание строк является «\ 0», когда вы печатаете ваш ответ:

recvdata[n] = 0; /* null terminate ----> this must be '\0'*/ 
if (fputs(recvdata, stdout) == EOF) 
err_sys("fputs error"); 

вы подушечка его ти «0», поэтому он, вероятно, приведет вас к segfault, когда fputs проанализируют вашу строку, чтобы распечатать ее.

Надеюсь, это поможет!

+0

В ASCII, '' \ 0'' == '0'. Нет никакого вреда быть ясным и использовать '' \ 0''. – michaelb958

+0

приятно знать! :) :) :) ty! – user2561272

Смежные вопросы