![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблемы с сокетами [D7, WinXP]
maxistent © (2008-01-10 20:00:00)Добрый вечер, ув. Мастера! Помогите разобраться вот в чем. Я нашел одну статью по сокетам и оттуда взял готовые кусочки кода для сервера и клиента. Вот они:
Код сервера:
var S,AcceptedSock:TSocket;
Addr:TSockAddr;
Data:TWSAData;
Len:Integer;
begin
WSAStartup($101,Data);
S:=Socket(AF_Inet,Sock_Stream,0);
Addr.sin_family:=PF_Inet;
Addr.sin_port:=HToNS(1234);
Addr.sin_addr.S_addr:=InAddr_Any;
FillChar(Addr.Sin_Zero,SizeOf(Addr.Sin_Zero),0);
Bind(S,Addr,SizeOf(TSockAddr));
Listen(S,SoMaxConn);
Len:=SizeOf(TSockAddr);
AcceptedSock:=Accept(S,@Addr,@Len);
{ Теперь Addr содержит адрес клиента, с которым установлено
соединение, а AcceptedSock - дескриптор, обслуживающий это
соединение. Допустимы следующие действия:
Send(AcceptedSock,…) - отправить данные клиенту
Recv(AcceptedSock,…) - получить данные от клиента
Accept(…) - установить соединение с новым клиентом }
Код клиента:
var S:TSocket;
Addr:TSockAddr;
Data:TWSAData;
begin
WSAStartup($101,Data);
S:=Socket(AF_Inet,Sock_Stream,0);
Addr.sin_family:=AF_Inet;
Addr.sin_port:=HToNS(1234);
Addr.sin_addr.S_addr:=Inet_Addr('127.0.0.1');
FillChar(Addr.Sin_Zero,SizeOf(Addr.Sin_Zero),0);
Connect(S,Addr,SizeOf(TSockAddr));
{ Теперь соединение установлено. Допустимы следующие действия:
Send(S,…) - отправить данные серверу
Recv(S,…) - получить данные от сервера }
Проблема в том, что локально (на одном компе) этот код работает, а через ИНЕТ почему-то сервер не реагирует на входящий коннект, кагбутта ево нету :-( а клиент при попытке коннекта вроде как подключается, но видно, что НЕ ТУДА, КУДА НАДО. Может в коде что-то не так? Подскажите, кто чем может...
maxistent (2008-01-11 21:53:00) [21]...единственное, что мне всё ещё не понятно, это как поймать момент дисконнекта? насколько я понимаю, инициатор должен сделать
ShutDown(socket,SD_BOTH);
CloseSocket(socket);
А что нужно сделать на другом конце "провода", чтобы об этом узнать?
Сергей М. (2008-01-11 19:42:00) [22]Мда...
maxistent (2008-01-11 17:55:00) [23]хм... странно... понаставил кругом проверок и всё заработало. если коннект НА САМОМ ДЕЛЕ есть - то пишет "коннектед", если нет - "коннекшн еррор". в чем же была проблема? неужели в проверках на наличие ошибок?!
WsaErr := WSAStartUp($101, Data);
if WsaErr <> 0 then
begin
writeln('WSA error');
readln;
exit;
end;
with Addr do
begin
sin_family := AF_INET;
sin_port := htons(1234);
sin_addr.S_addr := Inet_Addr('123.123.123.123');
end;
S := socket(AF_INET, SOCK_STREAM, 0);
if S = INVALID_SOCKET then
begin
writeln('Socket error');
readln;
exit;
end;
if Connect(S, Addr, SizeOf(Addr)) <> 0 then
begin
writeln('Connection error');
readln;
exit;
end;
Вот тут я уже точно знаю, есть коннект или нет. Странно... Ну и ладно, главное РАБОТАЕТ! Всем спасибо. Особенно Сергею М.! :)
FreeMem(maxistent);
maxistent (2008-01-11 17:22:00) [24]нашОл :(
> If no error occurs, connect returns zero. Otherwise, it returns SOCKET_ERROR,
> and a specific error code can be retrieved by calling WSAGetLastError.
Вот именно в соответствии с этим я и делаю вывод о том, что коннект произошел, т.е. результ=0 (ноу еррорс). =-o
Сергей М. (2008-01-11 15:49:00) [25]
> мне нужны именно примеры
Там ведь, в примерах тех самых, буковки нерусские) ..
И в справке тоже нерусские)
В чем разница-то ?)
> По поводу "я подключился": я не знаю, что НА САМОМ ДЕЛЕ
> там происходит
Ну так а какого ж лешего ты утверждаешь что подключился ?)
Вот тебе фрагмент справки, ищи знакомые букаффки:
Return Values
If no error occurs, connect returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
Нашел ?)
maxistent (2008-01-11 15:36:00) [26]В справке ПРИМЕРЫ редко встречаются. а мне нужны именно примеры, т.к. на примере мне легче понять и переделать под свою задачу (если, конечно, он мне подходит). Если бы все читали справку, ЭТИХ форумов (да и любых других) не было бы наверно...
По поводу TThread: я его не стал использовать не потому, что не умею код анализировать, или там... звезды встали раком... или ещё что-то :) там действительно много того, что мне совершенно не нужно. и при подключении модуля с этим TThread размер проги увеличивается. это тоже неприятно :( тем более, я уже нашел решение той задачи с потоками.
По поводу "я подключился": я не знаю, что НА САМОМ ДЕЛЕ там происходит, но учитывая все необходимые проверки и отсутствие ошибок при коннекте этот коннект устанавливается. Похоже, что код неверный :( я уже не знаю, что и думать...
Сергей М. (2008-01-11 14:15:00) [27]
> maxistent © (11.01.08 14:08) [3]
С учетом твоих претензий к TThread вырисовывается печальная картина твоего неумения читать и анализировать код)
И не надо уже маскировать этот факт под "слишком много напихано .. не нужного мне")
> если я совершенно "ЛЕВЫЙ" ИП укажу клиенту, то он всё-равно
> "подключается"
Что, прямо так и говорит - "я подключился" ?)
> Есть у кого-нить пример таких проверок?
Ты вообще хотя бы справку удосужился полистать-поштудировать, прежде чем код клянчить ?)
Или в справке тоже "слишком много напихано .. не нужного мне" ?)
maxistent (2008-01-11 14:08:00) [28]
> Slym © (11.01.08 04:28) [1]
Все необходимые проверки я ставил (брал из другого примера). От этого ничего не изменилось. Т.е. Клиент вроде подключается (причем, довольно долго), и в конце концов получается, что он подключился. Но я-то знаю, что никуда он не подключился :(
Про статью хочу сказать, что там есть инфа по поводу вызова функций и примеры. Поэтому я и воспользовался именно этой статьёй :)
И по поводу ИНЕТа. Если другими прогами коннектицо (использующими тот же T[Server/Client]Socket), коннект происходит и инфа передаёца! Вот поэтому я и обратился сюда за консультацией...
Самое интересное, что даже если я совершенно "ЛЕВЫЙ" ИП укажу клиенту, то он всё-равно "подключается". Что за хрень такая? Как быть? Может действительно СЕРЬЁЗНЫЕ проверки нужны? Есть у кого-нить пример таких проверок? Это одно, и второе: почему же всё-таки к реально существующему серваку в ИНЕТе не коннектица?
> Сергей М. © (11.01.08 08:07) [2]
не угодили :) слишком много "напихано"...не нужного мне. всё, что мне нужно, это:
от сервера: коннект (максимум до двух клиентов), дисконнект, read, write.
от клиента: коннект, дисконнект, read, write.
так что не ругайте меня за попытку изобретения велосипеда :) мне действительно нужно ИМЕННО ТАК.
Сергей М. (2008-01-11 08:07:00) [29]
> maxistent © (10.01.08 20:00)
Чем готовые компонентыне угодили ?
Slym (2008-01-11 04:28:00) [30]maxistent © (10.01.08 20:00)
Connect
функция, возвращающая результат. и не фукт что после вызова Connect произойдет "Теперь соединение установлено"- нет проверки...
maxistent © (10.01.08 20:00)
Я нашел одну статью по сокетам
если в статье не описано как вызывать функции то это плохая статья...
maxistent © (10.01.08 20:00)
через ИНЕТ почему-то сервер не реагирует
инет ничем не отличается от локально, кроме фсяких искуственных барьеров, поднятых для безопасности