C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Сокеты в билдере., Не соответствие с передаваемыми данными.
olegrolik
Отправлено: 25.12.2006, 21:50


Ученик-кочегар

Группа: Участник
Сообщений: 4



Код до тупого прост...:

int i,rv;
char buf;
RichEdit1->Clear();
Update();
SOCKET socket1;
WSADATA winSockData;
sockaddr_in peer;
char ipaddr[25];
sprintf(ipaddr,"%s",Edit4->Text);
// MessageBox(NULL,ipaddr,"",MB_OK);
unsigned short port;
int result,lis;
WSAStartup(0x0101, &winSockData);

socket1 = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
peer.sin_family = AF_INET;
peer.sin_port = htons(7777);
peer.sin_addr.s_addr = inet_addr(ipaddr);
result = connect(socket1, (sockaddr *) &peer, sizeof(peer));
if (result != 0) {
RichEdit1->Lines->Add("Couldn't connect to the server!");;
}
else {
RichEdit1->Lines->Add("Port is open");
}
peer.sin_family = AF_INET;
peer.sin_port = htons(7777);
peer.sin_addr.s_addr = inet_addr("87.242.73.175");
bind(socket1, (sockaddr *) &peer, sizeof(peer)); // не знаю — нужно ли это

RichEdit1->Lines->Add(send(socket1,&buf,4096,0));
// Sleep(10);
RichEdit1->Lines->Add(send(socket1,&buf,4096,0));
RichEdit1->Lines->Add(send(socket1,&buf,4096,0));
RichEdit1->Lines->Add(send(socket1,&buf,4096,0));
RichEdit1->Lines->Add(send(socket1,&buf,4096,0));
RichEdit1->Lines->Add(send(socket1,&buf,4096,0));
WSACleanup();
closesocket(socket1);
}

По идее посылаю по адресу 6 раз 4096 байт. В установке соединения проверяю реально ли отсылается 4096*6 байт. В итоге получается, что есть крупное не соответствие (даже при попытке послать 1 раз 4096 байт посылается то 3116 байт, то около 4200). Более того, не все отсылки работают. Первая — всегда, остальные в случайном порядке. Пробовал использовать Sleep() — не помогает.
Помогите, пожалуйста, решить проблему. Спасибо smile.gif
Doga
Отправлено: 25.12.2006, 22:54


Мастер участка

Группа: Участник
Сообщений: 575



Насколько я понимаю, для TCP (в отличие от UDP) сокета нет никакой гарантии что данные придут куском точно того же размера как и отправленные. Размер принятого пакета может быть и меньше и больше отправленного. Всё зависит от установленного размера внутренних передающего и приёмного буферов библиотеки WinSock. Настроить их размер можно с помощью getsockopt и setsockopt.

Но данные должны приходить всегда в том же порядке как отправлялись.

olegrolik
Отправлено: 25.12.2006, 23:13


Ученик-кочегар

Группа: Участник
Сообщений: 4



Но данные должны приходить всегда в том же порядке как отправлялись.

Т.е.?

Есть ещё вопрос:
сканировал порты в цикле функцией connect
получалось, что функция вызывается раз в секунду(примерно).
Т.е., если я хочу сканировать порты от 1до10000, то мне нужно 10000секунд, а это 166 минут.
Как быть?
Doga
Отправлено: 26.12.2006, 12:59


Мастер участка

Группа: Участник
Сообщений: 575



http://www.delphikingdom.com/asp/viewitem....?catalogid=1021

http://www.delphikingdom.com/asp/viewitem....?catalogid=1060


Вот здесь лежит хорошая статья на эту тему (2 части). Возможно, поможет...
olegrolik
Отправлено: 26.12.2006, 14:21


Ученик-кочегар

Группа: Участник
Сообщений: 4



Это для Delphi. Не очень хочется читать, даже если с практической точки зрения там всё реализовано также...
Я в принципе разобрался с проблемой передачи — уменьшил размер буфера с 4096 до 1024. Передаётся всё. Но опять же не соответствие. Не мог бы сказать как и в каких случаях пользоваться в функциями getsockopt и setsockopt?
Спасибо...
Doga
Отправлено: 26.12.2006, 21:28


Мастер участка

Группа: Участник
Сообщений: 575



QUOTE

Это для Delphi. Не очень хочется читать, даже если с практической точки зрения там всё реализовано также...


Ну что ж, не буду настаивать, хотя описание getsockopt и setsockopt там было cool.gif

Тогда, только MSDN rolleyes.gif


P.S. Если все данные передаются, то в чём, тогда, несоответствие? А уменьшение размеров буферов может привести к снижению скорости передачи данных...
olegrolik
Отправлено: 26.12.2006, 21:59


Ученик-кочегар

Группа: Участник
Сообщений: 4



Данные передаются не верно, если сравнивать по установленному соединению (два мониторчика в трее). Передаётся меньше, чем 1024 байта за каждый раз. Соответственно и принимается тоже. А если размер буфера сделать 4096 байт, то не факт, что на третий раз передача состоится.
Но теперь узнал, что функция send : The successful completion of a send does not indicate that the data was successfully delivered.
Вообще я хочу написать приложение на C++ builder, которое будет делать следующее. Я нахожусь в соединении с сервером. И записываю по очереди пакеты принятые и отправленные... Не подскажете как это сделать? Т.е. как определить приходит инфа мне от сервера и наоборот?

Вернуться в Вопросы программирования в C++Builder