Форум: "Сети";
Текущий архив: 2004.03.14;
Скачать: [xml.tar.bz2];
ВнизWinSock - первая программа Найти похожие ветки
← →
delpher_gray (2004-01-08 13:16) [0]Хочу написать очень маленький сервер (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-08 13:17) [1]WSAAsyncSelect(Sock, Wnd, WM_SOCKET, FD_ACCEPT+FD_READ); - вот на этой строке ошибка.
← →
Rouse_ (2004-01-08 13:38) [2]
int WSAAsyncSelect (
SOCKET s,
HWND hWnd,
unsigned int wMsg,
long lEvent
);
Parameters
s
[in] A descriptor identifying the socket for which event notification is required.
hWnd
[in] A handle identifying the window which should receive a message when a network event occurs.
wMsg
[in] The message to be received when a network event occurs.
lEvent
[in] A bitmask which specifies a combination of network events in which the application is interested.
А твоего обработчика я не вижу...
← →
Rouse_ (2004-01-08 13:40) [3]Т.е. ты должен указать оконную процедуру которая будет обрабатывать принимаемые сообщения...
Желаю успехов
← →
Delpher_Gray (2004-01-08 13:40) [4]Обработчика то и нет, я не знаю как писать...
Подскжите на примере пожалуйста...
← →
Delpher_Gray (2004-01-08 13:41) [5]А если у меня консольная программа !?
← →
Verg (2004-01-08 13:58) [6]
> Delpher_Gray © (08.01.04 13:41) [5]
> А если у меня консольная программа !?
1.Создать невидимое окно.
Пример: см. исходник ScktComp.pas
2. Использовать WSAEventSelect из WINSock2
3. Использовать select().
← →
Polevi (2004-01-08 13:59) [7]окно надо создать - 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;
← →
Delpher_Gray (2004-01-08 14:20) [8]А можно на полном примере !?
Я в этом плохо разбераюсь :((
← →
Delpher_Gray (2004-01-08 16:39) [9]Я тут кое-что написал, вот:
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" ?
← →
Polevi (2004-01-08 16:41) [10]WSAAsyncSelect(Sock, Wnd, WM_SOCKET, FD_ACCEPT+FD_READ); // ??? ??????
Wnd - это что у тебя такое ? где вызов CreateWindow ?
← →
Delpher_Gray (2004-01-08 16:48) [11]2Polevi:
ПОкажы плз на примере... CreateWindow( ... воот что тут писать то !? ... )
← →
Polevi (2004-01-08 18:04) [12]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 18:32) [13]Пасиба огромное !
Теперь я наткнулся ещё на одну ошибку...
Вот получившийся код программы:
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 20:01) [14]при каком приеме ? где у тебя вызов accept ???
← →
Delpher_Gray (2004-01-08 20:05) [15]Сорри, но я же сказал то в WinSock я совсем не рублю,
куда воткнуть accept !?
← →
Polevi (2004-01-08 20:05) [16]и вот эти строки
TranslateMessage(Msg);
DispatchMessage(Msg);
убери, они не нужны
и sleep твой тоже не нужен
← →
Delpher_Gray (2004-01-08 20:10) [17]Ага ясно, но а как мне всё-же принемать сообщения то !?
← →
Polevi (2004-01-08 20:19) [18]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;
← →
Polevi (2004-01-08 20:21) [19]>Delpher_Gray © (08.01.04 20:10) [17]
ты их принимаешь с помощью GetMessage
TranslateMessage вообще не нужен для консольной программы, DispatchMessage не нужен по причине отсутсвия у тебя оконной ф-ии
← →
Delpher_Gray (2004-01-08 20:36) [20]Вроде-бы всё понял, но немного теории...
Зачем новый сокет то нежен !? Или это старый !?
← →
имя (2004-01-09 00:22) [21]Удалено модератором
Примечание: И зачем тебе это?!! ...
← →
Rouse_ (2004-01-09 01:29) [22]Чесно говоря, я Удивился с Сергея (не в его стиле давать столь глобальную профилактику)...
Хинт: Есть понятия блокирующих и не блокирующих гнезд...
Но такой обширный ответ.... Сереж с Праздником...
← →
Polevi (2004-01-09 09:34) [23]>Delpher_Gray © (08.01.04 20:36) [20]
"старый" сокет слушает порт, а "новый" - подлючившийся клиент, полученый в результате вызова accept.
именно с "новым" сокетом возможны операции чтения/записи (send/recv)
>Rouse_ © (09.01.04 01:29) [22]
спасибо, тебя тоже :-)
← →
Delpher_Gray (2004-01-09 14:59) [24]Пасиба, буду разбираться.......
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.03.14;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.011 c