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() — не помогает.
Помогите, пожалуйста, решить проблему. Спасибо |
|
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 там было
Тогда, только MSDN
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, которое будет делать следующее. Я нахожусь в соединении с сервером. И записываю по очереди пакеты принятые и отправленные... Не подскажете как это сделать? Т.е. как определить приходит инфа мне от сервера и наоборот? |
|
|