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

Это убивает меня, и причина в моем отсутствии опыта работы с c / c ++.

Я не могу понять, как читать строку из другого потока. В этом случае поток поступает от клиента, который подключен к потоку сервера. Я смог передать ценные бумаги без каких-либо проблем. Однако я не могу понять, как передать строки.

клиентская сторона, которая читает строку с консоли и должна отправить на сервер:

cout << "Enter in an operation and number: \n ";
int x;
char str[20];
int len = strlen(str);
int result;


cin>>str;
cin>>x;

write(client_sock, &len, sizeof(int));
write(client_sock, str, len);
write(client_sock, &x, sizeof(x));

read(client_sock, &result, sizeof(result));
cout<<result;

сторона сервера, которая должна прочитать строку, для тестирования я пытаюсь отправить ее обратно, однако мне нужно прочитать ее и сравнить с другими условиями для выполнения операций над числами, которые я прочитал.

int result;
int input;
int len;
char str;

read(client_sock, &input, sizeof(input));
read(client_sock,&len,sizeof(len));
char buf[sizeof(len)];
sscanf(buf, "%s", &str);

cout<<str;
result= input*input;

write(client_sock,&result,sizeof(result));
write(client_sock, buf, strlen(buf));

Конечно, это задание, мой профессор сказал мне читать символами в буфер и завершать его нулем. Я не уверен, что он подразумевает под нулевым завершением .. также я правильно читаю в буфер?

Ответы [ 3 ]

1 голос
/ 20 ноября 2011

вот некоторые указатели

вам нужно делать одни и те же шаги как при написании, так и при чтении

, например, сначала записать длину (число байтов) строки в сокете, iугадайте в вашем случае одного байта должно быть достаточно для описания длины, после этого запишите строку в виде серии байтов.Если вы хотите иметь большие строки, используйте тип данных для длины, которая хорошо определена, а не int, например, сделайте свой собственный тип и имейте в виду, что если вы общаетесь между платформами, вам может потребоваться учитывать endianness .

то, что у вас есть на стороне записи, кажется нормальным (я полагаю, вы пропустили открытие / переплет и т.д. сокетов):

write(client_sock, &len, sizeof(unsigned char));
write(client_sock, str, len);

на стороне получателя высначала прочитайте длину, а затем это число следующих байтов:

read(client_sock, &len, sizeof(unsigned char));
char* buffer = new char[len + 1]; // create a buffer
read(client_sock, buffer, len);
buffer[len]='\0'; // terminate the string

теперь вы получили строку в буфере, просто преобразуйте ее в std :: string.

std::string s = buffer;
delete [] buffer; 

[заявление об отказе: не предназначено для полного или компилируемого кода для демонстрации принципа]

это неверные утверждения:

char buf[sizeof(len)];
sscanf(buf, "%s", &str);

buf неинициализирован и слишком мал, поскольку sizeof(len) будетверните размер только int, и вы практически читаете из неинициализированного буфера в строку, в которой есть место для одного байта.здесь нет необходимости в sscanf.

0 голосов
/ 20 ноября 2011

Несколько комментариев:

cout << "Enter in an operation and number: \n ";
int x;
char str[20];
int len = strlen(str);
int result;

Я не знаю о C ++, но C не будет автоматически обнулять вашу память для вас. Ваш char str[20] ; int len = strlen(str); работает strlen(3) на случайных памяти. Может содержать строку. Он может содержать указатели на функции из предыдущего стека вызовов. Он, безусловно, содержит мусор, и вызов strlen() для него также вызовет генерацию мусора - возможно, даже нарушение сегментации.

char str;
/* ... */
char buf[sizeof(len)];
sscanf(buf, "%s", &str);

Опять же, вы выделили буфер символов и немедленно передали его, неинициализированный, на sscanf(3). sscanf(3) будет читать мусор, и ничего, что он может сделать, не может быть правильным.

Кроме того, вы пытаетесь сохранить строку в один байт (char str). Вам нужно (а) изменить char str на char *str (б) фактически выделить для него немного памяти. Но, возможно, функция strdup(3) будет более полезной, поскольку похоже, что вы просто пытаетесь продублировать строку.

0 голосов
/ 20 ноября 2011

строка с нулевым символом в конце представляет собой стандартную строку c ... последовательность символов, за которой следует нулевой байт

в виде простой строки ascii "Hello" будет выглядеть как

0x48(H)
0x65 (e)
0x6c (л)
0x6c (л)
0x6f (o)
0x00 (NULL)

, как вы можете видеть, вынужен буфер с длиной строки + 1 байт (нулевой терминатор)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...