если вы видите этот текст, отключите в настройках форума использование JavaScript
Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания .
Новичкам также крайне полезно ознакомиться с данным документом .
Пример на WSAAsyncSelect 28.04.03 10:38 Число просмотров: 6543
Автор: ukv Статус: Незарегистрированный пользователь
// Module Name: asyncselect.cpp
//
// Description:
//
// This sample illustrates how to develop a simple echo server Winsock
// application using the WSAAsyncSelect() I/O model. This sample is
// implemented as a console-style application (to reduce the programming
// complexity of writing a real Windows application) and simply prints
// messages when connections are established and removed from the server.
// The application listens for TCP connections on port 5150 and accepts them
// as they arrive. When this application receives data from a client, it
// simply echos (this is why we call it an echo server) the data back in
// it's original form until the client closes the connection.
//
// Since the WSAAsyncSelect I/O model requires an application to manage
// window messages when network event occur, this application creates
// a window for the I/O model only. The window stays hidden during the
// entire execution of this application.
//
// Compile:
//
// cl -o asyncselect asyncselect.cpp ws2_32.lib user32.lib gdi32.lib
//
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define PORT 5150
#define DATA_BUFSIZE 8192
typedef struct _SOCKET_INFORMATION {
BOOL RecvPosted;
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;
SOCKET Socket;
DWORD BytesSEND;
DWORD BytesRECV;
_SOCKET_INFORMATION *Next;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;
#define WM_SOCKET (WM_USER + 1)
void CreateSocketInformation(SOCKET s);
LPSOCKET_INFORMATION GetSocketInformation(SOCKET s);
void FreeSocketInformation(SOCKET s);
HWND MakeWorkerWindow(void);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LPSOCKET_INFORMATION SocketInfoList;
void main(void)
{
MSG msg;
DWORD Ret;
SOCKET Listen;
SOCKADDR_IN InternetAddr;
HWND Window;
WSADATA wsaData;
if ((Window = MakeWorkerWindow()) == NULL)
return;
// Prepare echo server
if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Ret);
return;
}
if ((Listen = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("socket() failed with error %d\n", WSAGetLastError());
return;
}
WSAAsyncSelect(Listen, Window, WM_SOCKET, FD_ACCEPT|FD_CLOSE);
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(PORT);
if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return;
}
if (listen(Listen, 5))
{
printf("listen() failed with error %d\n", WSAGetLastError());
return;
}
// Translate and dispatch window messages for the application thread
while(Ret = GetMessage(&msg, NULL, 0, 0))
{
if (Ret == -1)
{
printf("GetMessage() failed with error %d\n", GetLastError());
return;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
SOCKET Accept;
LPSOCKET_INFORMATION SocketInfo;
DWORD RecvBytes, SendBytes;
DWORD Flags;
if (uMsg == WM_SOCKET)
{
if (WSAGETSELECTERROR(lParam))
{
printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
FreeSocketInformation(wParam);
}
else
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
if ((Accept = accept(wParam, NULL, NULL)) == INVALID_SOCKET)
{
printf("accept() failed with error %d\n", WSAGetLastError());
break;
}
// Create a socket information structure to associate with the
// socket for processing I/O.
CreateSocketInformation(Accept);
printf("Socket number %d connected\n", Accept);
WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);
break;
case FD_READ:
SocketInfo = GetSocketInformation(wParam);
// Read data only if the receive buffer is empty.
if (SocketInfo->BytesRECV != 0)
{
SocketInfo->RecvPosted = TRUE;
return 0;
}
else
{
SocketInfo->DataBuf.buf = SocketInfo->Buffer;
SocketInfo->DataBuf.len = DATA_BUFSIZE;
Flags = 0;
if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
&Flags, NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
FreeSocketInformation(wParam);
return 0;
}
}
else // No error so update the byte count
{
SocketInfo->BytesRECV = RecvBytes;
}
}
// DO NOT BREAK HERE SINCE WE GOT A SUCCESSFUL RECV. Go ahead
// and begin writing data to the client.
case FD_WRITE:
SocketInfo = GetSocketInformation(wParam);
if (SocketInfo->BytesRECV > SocketInfo->BytesSEND)
{
SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;
SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;
if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,
NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
FreeSocketInformation(wParam);
return 0;
}
}
else // No error so update the byte count
{
SocketInfo->BytesSEND += SendBytes;
}
}
if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)
{
SocketInfo->BytesSEND = 0;
SocketInfo->BytesRECV = 0;
// If a RECV occurred during our SENDs then we need to post an FD_READ
// notification on the socket.
if (SocketInfo->RecvPosted == TRUE)
{
SocketInfo->RecvPosted = FALSE;
PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
}
}
break;
case FD_CLOSE:
printf("Closing socket %d\n", wParam);
FreeSocketInformation(wParam);
break;
}
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void CreateSocketInformation(SOCKET s)
{
LPSOCKET_INFORMATION SI;
if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
sizeof(SOCKET_INFORMATION))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return;
}
// Prepare SocketInfo structure for use.
SI->Socket = s;
SI->RecvPosted = FALSE;
SI->BytesSEND = 0;
SI->BytesRECV = 0;
SI->Next = SocketInfoList;
SocketInfoList = SI;
}
LPSOCKET_INFORMATION GetSocketInformation(SOCKET s)
{
SOCKET_INFORMATION *SI = SocketInfoList;
while(SI)
{
if (SI->Socket == s)
return SI;
SI = SI->Next;
}
return NULL;
}
void FreeSocketInformation(SOCKET s)
{
SOCKET_INFORMATION *SI = SocketInfoList;
SOCKET_INFORMATION *PrevSI = NULL;
while(SI)
{
if (SI->Socket == s)
{
if (PrevSI)
PrevSI->Next = SI->Next;
else
SocketInfoList = SI->Next;
closesocket(SI->Socket);
GlobalFree(SI);
return;
}
PrevSI = SI;
SI = SI->Next;
}
}
HWND MakeWorkerWindow(void)
{
WNDCLASS wndclass;
CHAR *ProviderClass = "AsyncSelect";
HWND Window;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = ProviderClass;
if (RegisterClass(&wndclass) == 0)
{
printf("RegisterClass() failed with error %d\n", GetLastError());
return NULL;
}
// Create a window.
if ((Window = CreateWindow(
ProviderClass,
"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL)) == NULL)
{
printf("CreateWindow() failed with error %d\n", GetLastError());
return NULL;
}
return Window;
}
<programming >
[Net] Асинхронные/неблокирующие сокеты 27.04.03 07:37
Автор: Drow Elf Статус: Незарегистрированный пользователь
Если не очень тяжело, объясните, как с помощью ioctlsocket (в winsock) сделать неблокирующие сокеты, в смысле как разблокировать сокет с помощью этой функции я знаю, но как с помощью select в последствии проверять статус, что-то не очень понятно :(
Кстати есть ли принципиальная разница между асинхронными сокетами(WSA) и неблокирующими......... Thanks
Пример на WSAAsyncSelect 28.04.03 10:38
Автор: ukv Статус: Незарегистрированный пользователь
// Module Name: asyncselect.cpp
//
// Description:
//
// This sample illustrates how to develop a simple echo server Winsock
// application using the WSAAsyncSelect() I/O model. This sample is
// implemented as a console-style application (to reduce the programming
// complexity of writing a real Windows application) and simply prints
// messages when connections are established and removed from the server.
// The application listens for TCP connections on port 5150 and accepts them
// as they arrive. When this application receives data from a client, it
// simply echos (this is why we call it an echo server) the data back in
// it's original form until the client closes the connection.
//
// Since the WSAAsyncSelect I/O model requires an application to manage
// window messages when network event occur, this application creates
// a window for the I/O model only. The window stays hidden during the
// entire execution of this application.
//
// Compile:
//
// cl -o asyncselect asyncselect.cpp ws2_32.lib user32.lib gdi32.lib
//
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define PORT 5150
#define DATA_BUFSIZE 8192
typedef struct _SOCKET_INFORMATION {
BOOL RecvPosted;
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;
SOCKET Socket;
DWORD BytesSEND;
DWORD BytesRECV;
_SOCKET_INFORMATION *Next;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;
#define WM_SOCKET (WM_USER + 1)
void CreateSocketInformation(SOCKET s);
LPSOCKET_INFORMATION GetSocketInformation(SOCKET s);
void FreeSocketInformation(SOCKET s);
HWND MakeWorkerWindow(void);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LPSOCKET_INFORMATION SocketInfoList;
void main(void)
{
MSG msg;
DWORD Ret;
SOCKET Listen;
SOCKADDR_IN InternetAddr;
HWND Window;
WSADATA wsaData;
if ((Window = MakeWorkerWindow()) == NULL)
return;
// Prepare echo server
if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Ret);
return;
}
if ((Listen = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("socket() failed with error %d\n", WSAGetLastError());
return;
}
WSAAsyncSelect(Listen, Window, WM_SOCKET, FD_ACCEPT|FD_CLOSE);
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(PORT);
if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return;
}
if (listen(Listen, 5))
{
printf("listen() failed with error %d\n", WSAGetLastError());
return;
}
// Translate and dispatch window messages for the application thread
while(Ret = GetMessage(&msg, NULL, 0, 0))
{
if (Ret == -1)
{
printf("GetMessage() failed with error %d\n", GetLastError());
return;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
SOCKET Accept;
LPSOCKET_INFORMATION SocketInfo;
DWORD RecvBytes, SendBytes;
DWORD Flags;
if (uMsg == WM_SOCKET)
{
if (WSAGETSELECTERROR(lParam))
{
printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
FreeSocketInformation(wParam);
}
else
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
if ((Accept = accept(wParam, NULL, NULL)) == INVALID_SOCKET)
{
printf("accept() failed with error %d\n", WSAGetLastError());
break;
}
// Create a socket information structure to associate with the
// socket for processing I/O.
CreateSocketInformation(Accept);
printf("Socket number %d connected\n", Accept);
WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);
break;
case FD_READ:
SocketInfo = GetSocketInformation(wParam);
// Read data only if the receive buffer is empty.
if (SocketInfo->BytesRECV != 0)
{
SocketInfo->RecvPosted = TRUE;
return 0;
}
else
{
SocketInfo->DataBuf.buf = SocketInfo->Buffer;
SocketInfo->DataBuf.len = DATA_BUFSIZE;
Flags = 0;
if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
&Flags, NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
FreeSocketInformation(wParam);
return 0;
}
}
else // No error so update the byte count
{
SocketInfo->BytesRECV = RecvBytes;
}
}
// DO NOT BREAK HERE SINCE WE GOT A SUCCESSFUL RECV. Go ahead
// and begin writing data to the client.
case FD_WRITE:
SocketInfo = GetSocketInformation(wParam);
if (SocketInfo->BytesRECV > SocketInfo->BytesSEND)
{
SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;
SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;
if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,
NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
FreeSocketInformation(wParam);
return 0;
}
}
else // No error so update the byte count
{
SocketInfo->BytesSEND += SendBytes;
}
}
if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)
{
SocketInfo->BytesSEND = 0;
SocketInfo->BytesRECV = 0;
// If a RECV occurred during our SENDs then we need to post an FD_READ
// notification on the socket.
if (SocketInfo->RecvPosted == TRUE)
{
SocketInfo->RecvPosted = FALSE;
PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
}
}
break;
case FD_CLOSE:
printf("Closing socket %d\n", wParam);
FreeSocketInformation(wParam);
break;
}
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void CreateSocketInformation(SOCKET s)
{
LPSOCKET_INFORMATION SI;
if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
sizeof(SOCKET_INFORMATION))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return;
}
// Prepare SocketInfo structure for use.
SI->Socket = s;
SI->RecvPosted = FALSE;
SI->BytesSEND = 0;
SI->BytesRECV = 0;
SI->Next = SocketInfoList;
SocketInfoList = SI;
}
LPSOCKET_INFORMATION GetSocketInformation(SOCKET s)
{
SOCKET_INFORMATION *SI = SocketInfoList;
while(SI)
{
if (SI->Socket == s)
return SI;
SI = SI->Next;
}
return NULL;
}
void FreeSocketInformation(SOCKET s)
{
SOCKET_INFORMATION *SI = SocketInfoList;
SOCKET_INFORMATION *PrevSI = NULL;
while(SI)
{
if (SI->Socket == s)
{
if (PrevSI)
PrevSI->Next = SI->Next;
else
SocketInfoList = SI->Next;
closesocket(SI->Socket);
GlobalFree(SI);
return;
}
PrevSI = SI;
SI = SI->Next;
}
}
HWND MakeWorkerWindow(void)
{
WNDCLASS wndclass;
CHAR *ProviderClass = "AsyncSelect";
HWND Window;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = ProviderClass;
if (RegisterClass(&wndclass) == 0)
{
printf("RegisterClass() failed with error %d\n", GetLastError());
return NULL;
}
// Create a window.
if ((Window = CreateWindow(
ProviderClass,
"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL)) == NULL)
{
printf("CreateWindow() failed with error %d\n", GetLastError());
return NULL;
}
return Window;
}
[Net] Всегда считал, что асинхронные и есть неблокирующие 27.04.03 14:06
Автор: amirul <Serge> Статус: The Elderman
Неправильно ты считал. 06.05.03 17:57
Автор: L Статус: Незарегистрированный пользователь
а как тогда правильно? 07.05.03 08:32
Автор: Killer{R} <Dmitry> Статус: Elderman
цитата из МСДНа:
The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent. See the ioctlsocket functions for information on how to set the nonblocking socket back to blocking mode.
а как тогда правильно? 07.05.03 12:34
Автор: L Статус: Незарегистрированный пользователь
Читай контекст:
Автор> Кстати есть ли принципиальная разница между асинхронными сокетами(WSA) и неблокирующими
amirul>Всегда считал, что асинхронные и есть неблокирующие
Правильный ответ: не путать тёплое с мягким. Между асинхронными сокетами и non-blocking mode как раз такипринципиальная разница.
По понятиям 08.05.03 12:14
Автор: IgorR <Igor Razin> Статус: Member
> Читай контекст: >Между асинхронными сокетами и non-blocking mode как раз таки
>принципиальная разница.
Асинхронные сокеты говоришь? Не слышал про такие.
Действительно, междусокетами и mode есть разница.
ЗЫ. Все 4 модели асинхронного ввода-вывода (без select-а) подразумевают неблокирующий режим работы сокета.
<без заголовка> 09.05.03 00:45
Автор: L Статус: Незарегистрированный пользователь
> Асинхронные сокеты говоришь? Не слышал про такие. Теоретик? Или жажда правды обуяла? На MSDN это весьма расхожее словосочетание для обозначения асинхронного в/в с использованием сокетов.
> Действительно, междусокетами и mode есть разница. Ты практически точь-в-точь повторил мою фразу.
> ЗЫ. Все 4 модели асинхронного ввода-вывода (без select-а) > подразумевают неблокирующий режим работы сокета. Читай вопрос автора, ответ и моё замечание.
<без заголовка> 11.05.03 11:59
Автор: IgorR <Igor Razin> Статус: Member
> Теоретик? Или жажда правды обуяла? См ниже.
>Правильный ответ: не путать тёплое с мягким. Между асинхронными сокетами и non-blocking mode как раз такипринципиальная разница.
И это я ещё теоритик?
> > Действительно, междусокетами иmode есть разница. > Ты практически точь-в-точь повторил мою фразу. Ту, что выше? Гы. Глумлюсь я ;)
> > ЗЫ. Все 4 модели асинхронного ввода-вывода (без > select-а) подразумевают неблокирующий режим работы сокета. > Читай вопрос автора, ответ и моё замечание. Читал, прикинь?
Автор> Кстати есть ли принципиальная разница между асинхронными сокетами(WSA) и неблокирующими
amirul>Всегда считал, что асинхронные и есть неблокирующие
>Правильный ответ: не путать тёплое с мягким. Между асинхронными сокетами и non-blocking mode как раз такипринципиальная разница.
Твоё "замечание" абсолютно не в тему. Если есть что сказать по существу - говори, а так - выпендрёж.
<без заголовка> 13.05.03 03:21 Штраф: 30 [Ktirf , amirul ]
Автор: L Статус: Незарегистрированный пользователь
> Ту, что выше? Гы. Глумлюсь я ;) Проглумишься - возвращайся.
Я не врач из Кащенко, помочь ничем не могу.
<без заголовка> 09.05.03 01:04
Автор: Killer{R} <Dmitry> Статус: Elderman
итак:
1)асинхронные сокеты это сокеты позволяющие проводить в\в асинхронно, то бишь независимо самой проги
2)неблокирующие сокеты - это сокеты которые не блокируют выполнение программы. достигаетмся это выполнением в\в параллельно самой проге
или я чегото неправильно понимаю, или это одно и то же. Аснхронные сокеты не блокируют прогу а неблокирующие работают асинхронно Ж)
Не говори загадками. Растолкуй эти понятия мне, ламеру бестолковому Ж) 07.05.03 17:13
Автор: Killer{R} <Dmitry> Статус: Elderman