простая модель обслуживания клиента TCP в C: клиент не получает - PullRequest
0 голосов
/ 09 сентября 2011

Я делаю простой клиент-сервер TCP в c и пытаюсь отправить сообщение с клиента на сервер, но у меня возникают некоторые проблемы с ним.Сервер действительно отправляет сообщение (целочисленное значение> 0), но клиент не может его получить (целочисленное значение> 0), вот код: Клиент

#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>




int main()
{
    int s_id;
    char *msg = "hello";
    struct sockaddr_in serv_addr;
    s_id = socket (AF_INET, SOCK_STREAM, 0);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons (1156);
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    connect(s_id,(struct sockaddr *) &serv_addr, sizeof (struct sockaddr));
    int r = recv (s_id, (char *) msg, 9, 0);
    printf("%d \n", r );
    printf("%s \n", msg );

    return 0;
}

Сервер:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

int main()
{
       int s_id;
       char *msg = "connected";
       struct sockaddr_in my_addr, remote_addr;
       s_id = socket (PF_INET,SOCK_STREAM,0);
       my_addr.sin_family = AF_INET;
       my_addr.sin_port = htons(1156);
       my_addr.sin_addr.s_addr  = inet_addr("127.0.0.1");

       bind(s_id,(struct sockaddr *) &my_addr, sizeof(struct sockaddr));
       listen (s_id,5);
       int size = sizeof (struct sockaddr_in);
       int new_sd = accept (s_id, (struct sockaddr *) &remote_addr, &size);
       int s= send(new_sd, (void *)msg, 9, 0);
       printf("%d \n", s );
       return 0;
}

Выводы, которые я получаю (после первого запуска сервера, а затем клиента), на стороне сервера: 9 на стороне клиента: -1 привет

Я использую Ubuntu 11.04 и компилятор gcc.

Я надеюсь, что кто-то там может помочь.Спасибо

Умар

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011
char *msg = "hello";

Это строковый литерал . Это константа, и вы не можете ее изменить.

int r = recv (s_id, (char *) msg, 9, 0);

И вот вы пытаетесь написать в него.

Измените вашу декларацию на:

char msg[20];
memset(msg, 0, sizeof(msg));

Если вы сделаете это изменение, ваш код будет работать как положено.

В C вам придется распределять и управлять буферами - бесплатного обеда нет :)

Также обратите внимание на другой ответ от Николай Фетисов - вам действительно нужно проверять коды возврата для всех системных вызовов.

1 голос
/ 09 сентября 2011

Вы никогда не проверяете ошибки после любых системных вызовов . Все socket(2), connect(2) и т. Д. Возвращают -1 при ошибке, затем вы можете распечатать описание ошибки, скажем, perror(3) функция. На каждой странице справки по системному вызову перечислены возможные ошибки.

Редактировать 0:

Реальная проблема, вероятно, в том, на что указывает Брайан - вы пытаетесь получить данные в постоянную память на клиенте. Умирает ли он с сегфо?

...