![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
WinSock - первая программа [D6, Win95/98, WinXP]
delpher_gray © (2004-01-08 13:16:00)
Хочу написать очень маленький сервер (KOL, WinAPI) с использованием WinSock.
НАписал небольшую программку, но она не работает :(
program Server;
uses
KOL, Windows, WinSock;
var
Wnd: HWND;
hMutex: THandle;
Msg: TMSG;
Cancel: boolean;
Sock: TSocket;
WSAData : TWSAData;
Sin: TSockAddrIn;
Stream: PStream;
begin
hMutex := CreateMutex(nil, false, "Server");
if WaitForSingleObject(hMutex, 0) <> wait_TimeOut then
begin
Sock := WSAStartUp(101, WSAData);
Sock := Socket(AF_INET, SOCK_STREAM, 0);
WSAAsyncSelect(Sock, Wnd, WM_SOCKET, FD_ACCEPT+FD_READ); //
Delpher_Gray (2004-01-09 14:59:00) [1]
Пасиба, буду разбираться.......
Polevi (2004-01-09 09:34:00) [2]
>Delpher_Gray © (08.01.04 20:36) [20]
"старый" сокет слушает порт, а "новый" - подлючившийся клиент, полученый в результате вызова accept.
именно с "новым" сокетом возможны операции чтения/записи (send/recv)
>Rouse_ © (09.01.04 01:29) [22]
спасибо, тебя тоже :-)
Rouse_ (2004-01-09 01:29:00) [3]
Чесно говоря, я Удивился с Сергея (не в его стиле давать столь глобальную профилактику)...
Хинт: Есть понятия блокирующих и не блокирующих гнезд...
Но такой обширный ответ.... Сереж с Праздником...
имя (2004-01-09 00:22:00) [4]
Удалено модератором
Примечание: И зачем тебе это?!! ...
Delpher_Gray (2004-01-08 20:36:00) [5]
Вроде-бы всё понял, но немного теории...
Зачем новый сокет то нежен !? Или это старый !?
Polevi (2004-01-08 20:21:00) [6]
>Delpher_Gray © (08.01.04 20:10) [17]
ты их принимаешь с помощью GetMessage
TranslateMessage вообще не нужен для консольной программы, DispatchMessage не нужен по причине отсутсвия у тебя оконной ф-ии
Polevi (2004-01-08 20:19:00) [7]
case LOWORD(Msg.lParam) of
FD_ACCEPT:
begin
newsocket:=accept(...);
WSAAsyncSelect(newsocket,wnd,WM_SOCKET, FD_READ or FD_WRITE or FD_CLOSE);
end;
FD_READ:
begin
end;
FD_WRITE:
begin
end;
FD_CLOSE:
begin
end;
end;
Delpher_Gray (2004-01-08 20:10:00) [8]
Ага ясно, но а как мне всё-же принемать сообщения то !?
Polevi (2004-01-08 20:05:00) [9]
и вот эти строки
TranslateMessage(Msg);
DispatchMessage(Msg);
убери, они не нужны
и sleep твой тоже не нужен
Delpher_Gray (2004-01-08 20:05:00) [10]
Сорри, но я же сказал то в WinSock я совсем не рублю,
куда воткнуть accept !?
Polevi (2004-01-08 20:01:00) [11]
при каком приеме ? где у тебя вызов accept ???
Delpher_Gray (2004-01-08 18:32:00) [12]
Пасиба огромное !
Теперь я наткнулся ещё на одну ошибку...
Вот получившийся код программы:
program Server;
uses
KOL, Windows, WinSock;
var
WM_SOCKET: Cardinal;
Wnd: THandle;
Wc: WNDCLASS;
Msg: TMsg;
Cancel: boolean;
Sock: TSocket;
WSAData : TWSAData;
Sin: TSockAddrIn;
Stream: PStream;
begin
WM_SOCKET := RegisterWindowMessage("WM_SOCKET");
Wnd := CreateMutex(nil, false, "Server");
if WaitForSingleObject(Wnd, 0) <> wait_TimeOut then
begin
with Wc do
begin
Style:= 0;
lpfnWndProc:= @DefWindowProc;
cbClsExtra:= 0;
cbWndExtra:= 0;
hInstance:= 0;
hIcon:= 0;
hCursor:= 0;
hbrBackground:= 0;
lpszMenuName:= nil;
lpszClassName:= "Server";
hInstance := HInstance;
end;
Windows.RegisterClass(Wc);
Wnd := CreateWindowEx(WS_EX_TOOLWINDOW, wc.lpszClassName,
"", WS_POPUP {!0}, 0, 0, 0, 0, 0, 0, HInstance, nil);
Sock := WSAStartUp(101, WSAData);
Sock := Socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
WSAAsyncSelect(Sock, Wnd, WM_SOCKET, FD_ACCEPT+FD_READ);
Sin.sin_family := AF_INET;
Sin.sin_addr.S_addr := INADDR_ANY;
Sin.sin_port := htons(1001);
Bind(Sock, Sin, SizeOf(Sin));
Listen(Sock, SOMAXCONN);
Stream := NewMemoryStream;
Cancel := false;
while not Cancel do
begin
while GetMessage(Msg, 0, 0, 0) do
begin
if Msg.message = WM_SOCKET then
ShowMessage("WM_SOCKET");
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
Sleep(5);
end;
Stream.Free;
WSACleanUp;
end;
end.
Сообщение "WM_SOCKET" должно вылазить прикаждом приёме данных, а вылазит только при соединении :(
Polevi (2004-01-08 18:04:00) [13]
var
wc:WNDCLASS;
wnd:THandle;
begin
with wc do
begin
style:= 0;
lpfnWndProc:= @DefWindowProc;
cbClsExtra:= 0;
cbWndExtra:= 0;
hInstance:= 0;
hIcon:= 0;
hCursor:= 0;
hbrBackground:= 0;
lpszMenuName:= nil;
lpszClassName:= "WndClass1234";
hInstance := HInstance;
end;
Windows.RegisterClass(wc);
wnd:=CreateWindowEx(WS_EX_TOOLWINDOW, wc.lpszClassName,
"", WS_POPUP {!0}, 0, 0, 0, 0, 0, 0, HInstance, nil);
Delpher_Gray (2004-01-08 16:48:00) [14]
2Polevi:
ПОкажы плз на примере... CreateWindow( ... воот что тут писать то !? ... )
Polevi (2004-01-08 16:41:00) [15]
WSAAsyncSelect(Sock, Wnd, WM_SOCKET, FD_ACCEPT+FD_READ); // ??? ??????
Wnd - это что у тебя такое ? где вызов CreateWindow ?
Delpher_Gray (2004-01-08 16:39:00) [16]
Я тут кое-что написал, вот:
var
WM_SOCKET: integer;
...
begin
...
while not Cancel do
begin
while GetMessage(Msg, 0, 0, 0) do
begin
if Msg.message = WM_SOCKET then
ShowMessage("WM_SOCKET");
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
Sleep(5);
end;
...
end;
Почему при посылке данных серверу не вылазеет сообщение "WM_SOCKET" ?
Delpher_Gray (2004-01-08 14:20:00) [17]
А можно на полном примере !?
Я в этом плохо разбераюсь :((
Polevi (2004-01-08 13:59:00) [18]
окно надо создать - CreateWindow
а WM_SOCKET ловить тут
while GetMessage(Msg,0,0,0) do
begin
if Msg.Message=WM_SOCKET then
begin
case LOWORD(Msg.lParam) of
FD_ACCEPT:
begin
...
...
end;
end;
end;
Verg (2004-01-08 13:58:00) [19]
> Delpher_Gray © (08.01.04 13:41) [5]
> А если у меня консольная программа !?
1.Создать невидимое окно.
Пример: см. исходник ScktComp.pas
2. Использовать WSAEventSelect из WINSock2
3. Использовать select().
Delpher_Gray (2004-01-08 13:41:00) [20]
А если у меня консольная программа !?