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

Вниз

Передача срочных данных   Найти похожие ветки 

 
soloboev   (2001-11-21 14:36) [0]

Спецы, выручайте, надежда только на вас. Нужно передать на
машину с Windows срочные данные - send(s,"a",1,MSG_OOB). Убился уже, ничего не получается. Данные удается прочитать, только если сокет работает в неблокировочном режиме. Для меня этот режим поряду причин не приемлем. Если сокет работает в блокировочном режиме, возникает следующая ситуация. Командой ioctlsocket(s,SOICATMARK,r) определяю, что есть срочные данные. Это работает. После этого пытаюсь recv(s,oob_buf,1,MSG_OOB) - ждет до бесконечности. Посоветуйте пожалуйста что-нибудь, может хотя бы ссылку.


 
Digitman   (2001-11-22 08:40) [1]

объясни, чем в данном случае вызвана необходимость передавать строки в OOB-пакетах ?


 
soloboev   (2001-11-23 09:16) [2]

Ну, надо мне


 
Digitman   (2001-11-23 12:19) [3]

а принимающее гнездо имеет установленную опцию SO_OOBINLINE ? и вообще - оно SOCK_STREAM у тебя ?


 
soloboev   (2001-11-26 15:24) [4]

Вот это уже лучше. В общем, ситуация такая. Сокет естественно STREAM"ный.
Если включаешь опцию SO_OOBINLINE, определить наличие OOB данных можно ioctlsocket(s,SIOCATMARK,r); Но приэтом естественно recv(s,buf,1,0) ждет до бесконечности, а resv(s,buf,1,MSG_OOB) чудесно выполняется, но при этом
содержимое buf не меняется, а данные вылазят вообще черт-те когда. Дело
в том, что это все делается под Windows 98 и реально работает только
один способ - использовать функцию WSAAsyncSelect. Правда это неблокирующий сокет, но эту проблему я решил. Думал, что советов будет больше.


 
Digitman   (2001-11-26 16:22) [5]

>soloboev
"работает только один способ - использовать функцию WSAAsyncSelect".
Да ничего подобного ! Там, где работает WSAAsyncSelect, с тем же успехом будет работать и WSAEventSelect - оба режима переводят гнездо в неблокирующий режим


 
soloboev   (2001-11-28 11:24) [6]

Все правильно - но я описал рабочий вариант. Для функций, работающих с
WSAEventSelect у меня нет библиотек (описания функций, константы). Если
знаешь, где взять, подскажи.


 
Digitman   (2001-11-28 12:03) [7]

>soloboev
А какие тебе еще библиотеки-то нужны ? И WSAAsyncSelect и WSAEventSelect экспортируются одной и той же библиотекой WS2_32.DLL, описание их есть в хэлпе, работают очень похоже (в WSAEventSelect гнездо ассоциируется с объектом синхронизации, создаваемым по WSACreateEvent, а в WSAAsyncSelect гнездо ассоциируется с любым существующим hWnd).
Декларацию же WSAEventSelect и пример использования ты можешь найти в модуле SConnect.pas


 
soloboev   (2001-11-28 16:40) [8]

Там нет декларации например WSAWaitForMultipleEvents или WSA_MAXIMUM_WAIT_EVENTS, да и многих других нужных для этого метода
деклараций я не нашел. Не нашел в D5 и в D6. Видимо по ряду причин
тот способ, которым я воспользовался, самый приемлемый. Но это под
Windows 98. Под Linux например все описанные в документации способы
работают без проблем.


 
Digitman   (2001-11-28 16:53) [9]

1. Декларация всех потрохов Winsock2 есть в свободно распространяемом winsock2.pas. В сети море узлов, где можно скачать этот модуль.
2. Даже если у тебя нет какой-то декларации, у тебя под рукой есть хэлп, сотвори ее сам по образу и подобию их декларации в sconnect.pas.
3. На кой черт тебе этот WSAWaitForMultipleEvents ? Пользуйся обычным MsgWaitForMultipleObjects - он еще и сообщения, посланные потоку другими потоками, будет отслеживать (WSAWaitForMultipleEvents этого не делает!)


 
soloboev   (2001-12-03 15:38) [10]

Может подкинешь кусочек кода, в качестве иллюстрации


 
Digitman   (2001-12-03 15:50) [11]

Иллюстрации чего ? декларации или использования ? конкретно - чего ?


 
soloboev   (2001-12-04 11:42) [12]

Можно того и другого :-) по WSAEventSelect.


 
Digitman   (2001-12-04 13:55) [13]

модуль sconnect.pas (мог бы и сам сподобиться заглянуть туда)


interface
....

function LoadWinSock2: Boolean;

var
WSACreateEvent: function: THandle stdcall;
WSAResetEvent: function(hEvent: THandle): Boolean stdcall;
WSACloseEvent: function(hEvent: THandle): Boolean stdcall;
WSAEventSelect: function(s: TSocket; hEventObject: THandle; lNetworkEvents: Integer): Integer stdcall;
...

implementation
...

var
hWinSock2: THandle;
...
function LoadWinSock2: Boolean;
const
DLLName = "ws2_32.dll";
begin
Result := hWinSock2 > HINSTANCE_ERROR;
if Result then Exit;
hWinSock2 := LoadLibrary(PChar(DLLName));
Result := hWinSock2 > HINSTANCE_ERROR;
if Result then
begin
WSACreateEvent := GetProcAddress(hWinSock2, "WSACreateEvent");
WSAResetEvent := GetProcAddress(hWinSock2, "WSAResetEvent");
WSACloseEvent := GetProcAddress(hWinSock2, "WSACloseEvent");
WSAEventSelect := GetProcAddress(hWinSock2, "WSAEventSelect");
end;
end;

procedure FreeWinSock2;
begin
if hWinSock2 > HINSTANCE_ERROR then
begin
WSACreateEvent := nil;
WSAResetEvent := nil;
WSACloseEvent := nil;
WSAEventSelect := nil;
FreeLibrary(hWinSock2);
end;
hWinSock2 := 0;
end;

...

function TSocketTransport.GetWaitEvent: THandle;
begin
FEvent := WSACreateEvent;
WSAEventSelect(FSocket.SocketHandle, FEvent, FD_READ or FD_CLOSE);
Result := FEvent;
end;

...

procedure TTransportThread.Execute;

procedure SynchronizeException;
var
SendException: TObject;
begin
if RaiseList <> nil then
begin
SendException := PRaiseFrame(RaiseList)^.ExceptObject;
PRaiseFrame(RaiseList)^.ExceptObject := nil;
if Assigned(FTransport) and (SendException is ESocketConnectionError) then
FTransport.Connected := False;
PostMessage(FParentHandle, THREAD_EXCEPTION, 0, Integer(Pointer(SendException)));
end;
end;

var
msg: TMsg;
Data: IDataBlock;
Event: THandle;
Context: Integer;
begin
CoInitialize(nil);
try
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
ReleaseSemaphore(FSemaphore, 1, nil);
try
FTransport.Connected := True;
try
Event := FTransport.GetWaitEvent;
while not Terminated and FTransport.Connected do
try
case MsgWaitForMultipleObjects(1, Event, False, INFINITE, QS_ALLINPUT) of
WAIT_OBJECT_0:
begin
WSAResetEvent(Event);
Data := FTransport.Receive(False, 0);
if Assigned(Data) then
begin
Data._AddRef;
PostMessage(FParentHandle, THREAD_RECEIVEDSTREAM, 0, Integer(Pointer(Data)));
Data := nil;
end;
end;
WAIT_OBJECT_0 + 1:
begin
while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
begin
if (msg.hwnd = 0) then
case msg.message of
THREAD_SENDSTREAM:
begin
Data := IDataBlock(msg.lParam);
Data._Release;
Context := FTransport.Send(Data);
if msg.wParam = 1 then
begin
Data := FTransport.Receive(True, Context);
Data._AddRef;
PostMessage(FParentHandle, THREAD_RECEIVEDSTREAM, 0, Integer(Pointer(Data)));
Data := nil;
end else
PostMessage(FParentHandle, THREAD_SENDNOTIFY, 0, 0);
end;
THREAD_REPLACETRANSPORT:
begin
FTransport := ITransport(msg.lParam);
FTransport._Release;
end;
else
DispatchMessage(msg);
end
else
DispatchMessage(msg);
end;
end;
end;
except
SynchronizeException;
end;
finally
Data := nil;
FTransport.Connected := False;
end;
except
SynchronizeException;
end;
finally
FTransport := nil;
CoUninitialize();
end;
end;




 
soloboev   (2001-12-05 09:22) [14]

Спасобо, открыл глаза.



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

Форум: "Сети";
Текущий архив: 2002.02.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.005 c
14-79436
помогите
2002-01-02 13:42
2002.02.25
Помогите с массивами


1-79365
DimaIv
2002-02-08 16:38
2002.02.25
Как правильно обьявлять функции при помощи Overload


14-79462
Dmitry69
2002-01-10 02:25
2002.02.25
Помогите нужна прога FSDialer v3.1 Build 248


1-79399
Aleksey_K
2002-02-08 12:14
2002.02.25
Пароль


1-79375
greenrul
2002-02-08 20:24
2002.02.25
Как свой checkbox и radiobutton сотворить?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский