Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.046 c
4-1155821441
apic
2006-08-17 17:30
2006.12.24
Короткий путь


15-1165178576
Real
2006-12-03 23:42
2006.12.24
Тюнеры от AverMedia - управление громкостью


6-1153916814
KyRo
2006-07-26 16:26
2006.12.24
TIdFtp


3-1160635903
leonid
2006-10-12 10:51
2006.12.24
Как создать dbf-файл?


2-1165406609
Riply
2006-12-06 15:03
2006.12.24
Была такая ветка:





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский