Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.24;
Скачать: CL | DM;

Вниз

Приём сообщений от сервера   Найти похожие ветки 

 
Andr-04   (2006-07-31 15:12) [0]

Добрый день. Как обойтись без использования WSAAsyncSelect для отправления сообщений от сервера и их приёма КЛИЕНТОМ?


 
Сергей М. ©   (2006-07-31 15:29) [1]

Прямо так и обойтись - не используя WSAAsyncSelect.


 
Andr-04   (2006-07-31 15:30) [2]

Т.е. как клиенту принимать сообщения от сервера в блокирующем режиме? И, если нужно, что должен выполнить сервер перед самой функцией send? Спасибо.


 
Сергей М. ©   (2006-07-31 15:32) [3]


> как клиенту принимать сообщения от сервера в блокирующем
> режиме?


прямо так и принимать - recv()


> что должен выполнить сервер перед самой функцией send?


Ты со стула упал ?
Или не понимаешь , что такое "вопрос-ответ" при общении клиента с сервером ?


 
Andr-04   (2006-07-31 15:42) [4]

Нет, не получается. Перечислю ключевые вызовы процедур из своей программы:
<CODEvar
 fSocket: TSocket;
 fBufSize, sz: Integer;
 sa: TSockAddr;
begin
 fSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
 if fSocket <> INVALID_SOCKET then
   begin
     FillChar(sa, SizeOf(TSockAddr), 0);
     sa.sin_family := AF_INET;
     sa.sin_port := htons(Port);
     sa.sin_addr.S_addr := inet_addr(PChar(IP));
     if connect(fSocket, sa, SizeOf(TSockAddr))>-1 then
       if listen(fSocket, SOMAXCONN)=0 then
         begin
           sz:=sizeOf(fBufSize);
           getsockopt(fSocket, SOL_SOCKET, SO_RCVBUF, PChar(@fBufSize), sz);
           sz:=send(fSocket, buf, sz, 0);
           ...
           sz:=recv(fSocket, buf[0], fBufSize, 0);
         end;
   end;
end;>
При описанном выше варианте sz, та, что возвращается после recv, всегда -1. Вот я и спрашиваю как это исправить?


 
Andr-04   (2006-07-31 15:48) [5]

Нет, не получается. Перечислю ключевые вызовы процедур из своей программы:
var
fSocket: TSocket;
fBufSize, sz: Integer;
sa: TSockAddr;
begin
fSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if fSocket <> INVALID_SOCKET then
  begin
    FillChar(sa, SizeOf(TSockAddr), 0);
    sa.sin_family := AF_INET;
    sa.sin_port := htons(Port);
    sa.sin_addr.S_addr := inet_addr(PChar(IP));
    if connect(fSocket, sa, SizeOf(TSockAddr))>-1 then
      if listen(fSocket, SOMAXCONN)=0 then
        begin
          sz:=sizeOf(fBufSize);
          getsockopt(fSocket, SOL_SOCKET, SO_RCVBUF, PChar(@fBufSize), sz);
          sz:=send(fSocket, buf, sz, 0);
          ...
          sz:=recv(fSocket, buf[0], fBufSize, 0);
        end;
  end;
end;

При описанном выше варианте sz, та, что возвращается после recv, всегда -1. Вот я и спрашиваю как это исправить?

Нет, со стула я не падал - просто мы посты [1] и [2] отправили почти в одно время, поэтому я и не успел прочитать Ваш ответ. Просто я с сокетами всегда только в блокирующем режиме работал, с организацией нескольких потоков. Сейчас всё равно исправлять буду на неблокирующий режим, но, всё-же, в одном месте моей программы лучше использовать блокирующий режим (там осуществлена работа без потоков и необходимо ожидание результата).


 
Ketmar ©   (2006-07-31 21:27) [6]

??? connect(), а потом listen()? или Вы с какими-то марсианскими сокетами работали, или странные очень мануалы курили...
есть подозрение, что остальной код "работы" примерно на том же уровне. я угадал?


 
DiamondShark ©   (2006-08-01 00:21) [7]


> connect(), а потом listen()?

технология клиент-сервер.


 
Andr-04   (2006-08-01 00:50) [8]

Не ругайте сильно! Если бы я знал что писать, то не спрашивал бы. Я никогда не сталкивался с необходимостью принимать сообщения от сервера. И что в этом такого страшного? Всё бывает когда-то первый раз! Если вас раздражают подобные вопросы - не пишите ответы. Со своей стороны я тоже пытаюсь найти ответ - ищу справочную литературу. Так оказалось, что сначала ничего найти не удавалось, поэтому, ради экономии времени, и задал вопрос здесь. Но ответа найти пока не удалось.


 
Сергей М. ©   (2006-08-01 08:11) [9]


> Andr-04   (01.08.06 00:50) [8]


listen() никогда не используется на стороне клиента, это ф-ция сервера.


 
Сергей М. ©   (2006-08-01 08:15) [10]


> Andr-04


В целм код ужасный.
Почитай book.itep.ru, разделы "Winsock" и "Протокол TCP", там есть красочная циклограмма, наглядно иллюстрирующая, какие ф-ции и в какой последовательности вызываются на стороне сервера и на стороне клиента и что при этом происходит в недрах протокола.


 
Ketmar ©   (2006-08-01 09:59) [11]

>DiamondShark ©   (01.08.06 00:21) [7]
Дим, это технология "а вот сколько всяких функция й знаю". %-)

>Andr-04   (01.08.06 00:50) [8]
что характерно (ц), нужные ответы есть в справке, идущей вместе с Delphi. надо только не лениться читать и думать.


 
Andr-04   (2006-08-01 14:52) [12]

Читаю, читаю... Говорил же уже! Правда, глаза сильно устают - принтер старый сломался, а шестерёнок нигде нету. А на счёт Listen - я её убирал - при отладке заметил, что ответ от неё -1, но это проблему не решило.


 
Сергей М. ©   (2006-08-01 15:03) [13]


> Andr-04   (01.08.06 14:52) [12]


Ну хорошо.
Предположим, огр.кучу док-ции в эл.виде действительно читать тяжело.

Но прочитать десяток-другой строк из справки к recv() вполне можно было !

Ведь там черным по белому написано (цитата из справки к recv):

Return Values

If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError

Т.е. если ты получил -1, первоечто ты должен сделать - вызвать WSAGetLastError, получить код конкретной ошибки, проанализировать его и в зависимости от причин ветвить свой алгоритм.
Ты это сделал ?
Нет, не сделал.
Ну так а что же ты хочешь тогда ?!


 
Ketmar ©   (2006-08-01 15:53) [14]

а можно пояснить глубокий эзотерический смысл вызова getsockopt()? или это опять из серии "а я в справке новую функцию нарыл"?

далее. очень интересно, что такое buf, какого оно размера, и почему в одном месте просто buf, а в другом -- buf[0]?

ну и: что, таки, возвращает WSAGetLastError(), как справедливо поинтересовался Сергей М.?


 
Andr-04   (2006-08-01 15:55) [15]

Я понял, что Listen не нужен и всё. А остальное всё оставил. Пока решил зрение напрягать. Может ещё за одно что узнаю, чем читать на английском описание каждой функции/процедуры.


 
Сергей М. ©   (2006-08-01 16:53) [16]


> Может ещё за одно что узнаю


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

Ибо ты никак не прореагировал на WSAGetLastError.


 
Ketmar ©   (2006-08-01 18:50) [17]

>Andr-04   (01.08.06 15:55) [15]
ничего ты не понял. "понял" -- это не "и всё", а "потому что".

>Сергей М. ©   (01.08.06 16:53) [16]
тут, похоже, просто ждут, пока весь нужный текст из справки на русский переведут. вот ты в [13] начал, после чего в [15] честно признались. %-)


 
Ketmar ©   (2006-08-01 18:54) [18]

кстати, только что обратил внимание на дезинформацию в [5]: "я с сокетами всегда только в блокирующем режиме работал". после чего желание как-то помогать пропало вовсе -- не люблю лжецов.


 
Andr-04   (2006-08-02 12:38) [19]

Да, в блокирующем и работал. Но не было необходимости принимать сообщения от сервера!
А я тем временем упорно разбирал документацию и переводил часть кода на асинхронный режим. Короче, в приведённом мной коде в [5] WSAGetLastError выдаёт WSAEFAULT (10014).
Прошу извинить за всё написанное мной выше - постараюсь больше этого не делать: буду писать сюда только после достаточного чтения доки и не экономить время на этом! Ато отвечают тут быстро :-) Спасибо!


 
Сергей М. ©   (2006-08-02 12:50) [20]

WSAEFAULT (10014) The buf argument is not totally contained in a valid part of the user address space.


 
Andr-04   (2006-08-02 13:17) [21]

Да знаю я описание этой ошибки. Только не понимаю почему она возникает! Переменная ига описана как динамический массив (array of byte), размер которого устанавливется предварительно при помощи SetLength, где в качестве размера выступает fBufSize.


 
Сергей М. ©   (2006-08-02 13:28) [22]


> не понимаю почему она возникает


А нефиг манипулировать GetSockOpt(), если не понимаешь, что там происходит и почему.


 
Ketmar ©   (2006-08-02 13:31) [23]

> [21] Andr-04   (02.08.06 13:17)

тогда с чего делается send() с просто buf? и советую проверить, не используется ли buf ещё где-то таким же образом. просто buf даст указатель совсем не туда, куда buf[0].


 
Andr-04   (2006-08-02 13:43) [24]

И с buf, и с buf[0], и с простой переменной типа Cardinal. Ещё пробовал использовать ioctlsocket(fSocket,FIONREAD,sz), после выполнения которой sz возвращает 0. Но Send работает без проблем! И ещё: если Send вызывать с buf[0], то она тоже вернёт (-1)!


 
Сергей М. ©   (2006-08-02 13:46) [25]

Тебе вообще накой ляд Winsock потребовался ?
Чем готовые компоненты не устроили ?


 
Сергей М. ©   (2006-08-02 13:48) [26]


> если Send вызывать с buf[0], то она тоже вернёт (-1)


Угу .. И еще неделю выяснять будем, что говорит при этом WSAGetLastError()

И накой тут сдался дин.массив - одному тебе известно.


 
Andr-04   (2006-08-02 14:09) [27]

Значение какой массив - динамический или статический не имеет.
> И еще неделю выяснять будем, что говорит при этом WSAGetLastError()
Не утрируйте! WSAGetLastError выдаёт 0, т.е. всё OK. А использовать готовые компоненты смысла нет - модуль пишу. Для чего - не скажу, потому что унижать будете! Вобщем, это не имеетзначения!


 
Andr-04   (2006-08-02 14:21) [28]

Ну я и мудило! Столько и времени, и места на форуме угробыл! Мда... Короче, тему можно закрыть, а лучше и удалить, потому что от неё больше никакого толка никому не будет! Я в сервере указывал на передачу пустого буфера из Stream, из-за того, что забыл назначить нулевую позицию именно в Stream"е! И читаю конец, спокойный такой! Не внимательно получилось!


 
Сергей М. ©   (2006-08-02 14:28) [29]


> Andr-04   (02.08.06 14:09) [27]


> Значение какой массив - динамический или статический не
> имеет


Может и не имеет. А вот выбор размера массива имеет.


> WSAGetLastError выдаёт 0


Этого не может быть. потому что этого не может быть никогда (с)

Справка к send() гласит:

Return Values

If no error occurs, send returns the total number of bytes sent. (Note that this can be less than the number indicated by len.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Ты когда-нибудь научишься ее читать, ту самую справку ?


> использовать готовые компоненты смысла нет - модуль пишу


С каких пор использование готовых компонентов потеряло смысл ?
И при чем здесь модуль ?


> Для чего - не скажу


Сексот ты наш)


> это не имеетзначения


Имеет ! Еще как имеет !

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


 
Сергей М. ©   (2006-08-02 14:30) [30]


> в сервере указывал на передачу пустого буфера из Stream,
>  из-за того, что забыл назначить нулевую позицию именно
> в Stream"е! И читаю конец, спокойный такой


Ты гонишь.

recv() в этом случае никак не может вернуть SOCKET_ERROR.


 
Andr-04   (2006-08-02 14:44) [31]

У меня теперь другая проблема - после вызова send программа аварийно завершается, хотя сервер это сообщение благополучно получает!..


 
Сергей М. ©   (2006-08-02 14:52) [32]

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


 
Andr-04   (2006-08-02 14:59) [33]

А, всё, разобрался! Форум уже в чат превратился по моей милости! Опять неправильно с динамическим массивом работал. ВЕЗДЕ нужно указывать buf[0]! Да будет это мне уроком! Очень извиняюсь за отнятое время! Спасибо всем!


 
Сергей М. ©   (2006-08-02 15:00) [34]

Малацца.
Еще бы ты разобрался с Get/SetSockOpt - цены б тебе не было.


 
Andr-04   (2006-08-02 15:01) [35]


> Проотладчик ты, разумеется, слыхом не слыхивал.
> Значит тебе пора закругляться с потугами на поприще программинга.

Какраз-таки отладчик мне это и сказал! А программировать заканчивать я и не думаю! Ещё только 6 лет программирую - мало ещё! :-)


 
Andr-04   (2006-08-02 15:07) [36]


> Еще бы ты разобрался с Get/SetSockOpt - цены б тебе не было.

Да, уже и с этим успел познакомиться, но лишь всколзь. Если будут опять проблемы - впервую очередь это почитаю! Мне очень помогла статья из королевства
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1021&mode=print Ну и её вторая часть...


 
Сергей М. ©   (2006-08-02 15:08) [37]

Ну тады, возвращаясь к нашим баранам, какое отношение все это имеет к  WSAAsyncSelect ?


 
medved_68 ©   (2006-08-02 15:12) [38]


> Ещё только 6 лет программирую - мало ещё! :-)


> нужно указывать buf[0]!

Шесть лет!!!! Ну вот сейчас ты точно гонишь.


 
Ketmar ©   (2006-08-02 15:36) [39]

> [33] Andr-04   (02.08.06 14:59)

я тебе на это уже давно намекал. %-)


 
Сергей М. ©   (2006-08-02 15:41) [40]


> medved_68 ©   (02.08.06 15:12) [38]


> ты точно гонишь


"Эт точно" (с) Сухов



Страницы: 1 2 3 вся ветка

Текущий архив: 2006.12.24;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.039 c
2-1165314415
Stanislav
2006-12-05 13:26
2006.12.24
Динамический массив


15-1163681010
sergey888
2006-11-16 15:43
2006.12.24
Delphi уже относится к "другим" языкам программирования


2-1165330960
Creative
2006-12-05 18:02
2006.12.24
Создание кнопки


15-1164886688
flaxe
2006-11-30 14:38
2006.12.24
Дискретная Математика!


15-1164794548
GRAND25
2006-11-29 13:02
2006.12.24
В защиту СУБД FireBird