LINUX.ORG.RU

Сокеты, Передача данных, C/C++


0

0

Привет всем!
Сел сейчас разбираться с сокетами, столкнулся с проблемой: как принять данные до их конца? Я, например, не врубился :(, и вынужден просить помощи на форуме. Пожалуйста помогите!
-----
/*
КЛИЕНТ
*/
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/poll.h>
#include <fcntl.h>

using namespace std;

const char *addr = "localhost";
const int port = 15908;

typedef void* ptr;

typedef struct
{
char ver;
char type;
int len;
ptr data;
} our_packet;

int main()
{
struct sockaddr_in name;
struct timeval timeout;
struct hostent *hostinfo = NULL;

if (!(hostinfo = gethostbyname(addr)))
{
cout << "fuck! gethostbyname failed! :(" << endl;
return 1;
}

int sock = socket(PF_INET, SOCK_STREAM, 0);
name.sin_addr = *((struct in_addr *)hostinfo -> h_addr);
name.sin_port = htons(port);
name.sin_family = AF_INET;

if (connect(sock, (sockaddr *)&name, sizeof(struct sockaddr_in)) == -1)
{
cout << "fuck! connect failed! :(" << endl;
return 2;
}

our_packet pkg;
pkg.ver = 1;
pkg.type = 2;
pkg.data = (ptr)"test\0";
pkg.len = strlen((char*)(pkg.data));

ptr tosend = &pkg;
int len = sizeof(pkg);

int total = 0, n = 0;
while (total < n)
{
if ((n = send(sock, (char*)tosend + total, len - total, 0)) == -1)
{
cout << "fuck! send failed! :(" << endl;
return 3;
}
total += n;
}
cout << total << " of " << len << "bytes sent..." << endl;

char buf[1024];
if (recv(sock, buf, 1024, 0) <= 0)
{
cout << "fuck! recv failed! :(" << endl;
return 4;
}
close(sock);

if (strcmp(buf, "ok") == 0)
{
cout << "all done!" << endl;
return 0;
} else {
cout << "fuck off %)" << endl;
return 5;
}
}
-----
/*
СЕРВЕР
*/
#include <iostream>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>

using namespace std;

const int port = 15908;

typedef void* ptr;

typedef struct
{
char ver;
char type;
int len;
ptr data;
} our_packet;

int main()
{
int sock = socket(PF_INET, SOCK_STREAM, 0);

struct sockaddr_in addr;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
addr.sin_family = AF_INET;

if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
{
cout << "fuck! bind failed! :(" << endl;
return 1;
}

if (listen(sock, 2) != 0)
{
cout << "fuck! listen failed! :(" << endl;
return 2;
}

int nsock = accept(sock, NULL, NULL);
if (nsock == -1)
{
cout << "fuck! accept failed! :(" << endl;
return 3;
}
char buf[1024];
if (recv(nsock, buf, 1024, 0) <= 0)
{
cout << "fuck! recv failed! :(" << endl;
return 4;
}
// что делать с принятыми данными, чтобы сформировать структуру типа our_packet точно такую же, как и у клиента?

sprintf(buf, "ok");
if (send(nsock, buf, 1024, 0) <= 0)
{
cout << "fuck! send failed! :(" << endl;
return 5;
}
close(sock);
return 0;
}
----
PS: что-то в мыслях у меня туманно :(


pkg.data = (ptr)"test\0";

хм... Что бы это могло значить? Зачем клиенту получать значение указателя, вместо самих данных, куда это указывает?

int len = sizeof(pkg);

- у тебя размер sizeof(pkg) - всегда фиксированный (плюс, что на приемной платформе он всё же может отличатся - от компилятора зависит etc...)

Т.е. реально данные pkg.data ты естественно не можешь передать таким образом.

Просто сделай - отдельно передачу размера, после чего, другим пакетом (серией) - данные; на приемной стороне - прими длину сообщения, после чего лови данные нужной длины, или до обрыва соединения, или же - до ошибки передачи.

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

Spectr ★★★
()
Ответ на: комментарий от Spectr

НИКОГДА НЕ ПЕРЕДАВАЙ СТРУКТУРУ В СОКЕТ!!!!!! За это и убить могут... Есть же порядок байтов - это раз, а также выравнивание, которое зависит от компилятора, то есть получать будешь мусор. Лучше не ;би себе мозги мозги и почитай про ACE, всё что ты написал на ACE пишется на порядок быстрее и короче.

anonymous
()
Ответ на: комментарий от anonymous

>...и почитай про ACE, всё что ты написал на ACE пишется на порядок быстрее и короче

Ссылку в студию

KIV
()
Ответ на: комментарий от anonymous

>НИКОГДА НЕ ПЕРЕДАВАЙ СТРУКТУРУ В СОКЕТ!!!!!!

Не слушай его, никто не убьет. Просто делай это аккуратно....

>Есть же порядок байтов - это раз, а также выравнивание, которое зависит от компилятора,

... управляя как порядком байт так и выравниванием

KIV
()
Ответ на: комментарий от EViL

> можно кинуть сюда измененную версию моего быдлокода? я уж сам разберусь.

Spectr все объяснил - читай внимательно

KIV
()
Ответ на: комментарий от anonymous

> Есть же порядок байтов - это раз, а также выравнивание
Что такое "выравнивание"?

> Лучше не ;би себе мозги мозги и почитай про ACE, всё что ты написал на ACE пишется на порядок быстрее и короче.
Давай ка я лучше не буду учить какой-то быдлоязычок, а осилю сабж на сях?

EViL
() автор топика
Ответ на: комментарий от EViL

>Давай ка я лучше не буду учить какой-то быдлоязычок, а осилю сабж на сях?

давай только почему же ты тогда полез в плюсы?

cvv ★★★★★
()
Ответ на: комментарий от EViL

ну так если тебе нужны плюсы - чего шыпиш на ACE?

это именно то что доктор прописал. ну есть ещё OpenTop.

а не нравится - зачем тогда тыкался в плюсы?

cvv ★★★★★
()
Ответ на: комментарий от EViL

Вот ты сначала хоть что-то нормальное напиши, а уже потом рассуждай, что является быдлоязыком, а что нет. Ты бы сначала почитал про сабж(ACE), а уже потом бы палку гнул.

anonymous
()
Ответ на: комментарий от anonymous

Только у OpenTopа лицензия не красивая! Лучше уж ACE.

anonymous
()
Ответ на: комментарий от anonymous

> Вот ты сначала хоть что-то нормальное напиши, а уже потом рассуждай, что является быдлоязыком, а что нет. Ты бы сначала почитал про сабж(ACE), а уже потом бы палку гнул.
Умри, ниасиливший регистрацию!

EViL
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.