TCP流式套接字的非同步事件WSAAsyncSelect程式設計
阿新 • • 發佈:2019-02-10
#include <WINSOCK2.H>
/*#include <windows.h>*/
#pragma comment(lib,"WS2_32")
//----------------視窗過程函式的宣告-------------
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
//----------------WinMain()函式------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
{
WNDCLASS wc;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc=WindowProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_EXCLAMATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName="Test"
//---註冊視窗類----
RegisterClass(&wc);
//---建立視窗----
HWND hwnd=CreateWindow("Test","視窗標題",WS_SYSMENU,300,0,600,400,NULL,NULL,hInstance,NULL);
if (hwnd==NULL)
{
MessageBox(hwnd,"建立窗口出錯","標題欄提升",MB_OK);
return 1;
}
//---顯示視窗----
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//---socket-----
WSADATA wsaData;
WORD wVersionRequested=MAKEWORD(2,2);
if (WSAStartup(wVersionRequested,&wsaData)!=0)
{
MessageBox(NULL,"WSAStartup() Failed","呼叫失敗",0);
return 1;
}
SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (s==INVALID_SOCKET)
{
MessageBox(NULL,"socket() Failed","呼叫失敗",0);
return 1;
}
sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(1111);
sin.sin_addr.S_un.S_addr=inet_addr("192.168.31.1");
if (bind(s,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
MessageBox(NULL,"bind() Failed","呼叫失敗",0);
return 1;
}
if (listen(s,3)==SOCKET_ERROR)
{
MessageBox(NULL,"listen() Failed","呼叫失敗",0);
return 1;
}
else
MessageBox(hwnd,"進入監聽狀態!","標題欄提示",MB_OK);
WSAAsyncSelect(s,hwnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE);
//---訊息迴圈----
MSG msg;
while (GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
closesocket(s);
WSACleanup();
return msg.wParam;
}
//-------------------視窗過程----------------------
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_SOCKET:
{
SOCKET ss=wParam; //wParam引數標誌了網路事件發生的套介面
if (WSAGETSELECTERROR(lParam))
{
closesocket(ss);
return 0;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT: //-----①連線請求到來
{
sockaddr_in Cadd;
int Cadd_len=sizeof(Cadd);
SOCKET sNew=accept(ss,(sockaddr*)&Cadd,&Cadd_len);
if (ss==INVALID_SOCKET)
MessageBox(hwnd,"呼叫accept()失敗!","標題欄提示",MB_OK);
WSAAsyncSelect(sNew,hwnd,WM_SOCKET,FD_READ|FD_CLOSE);
}break;
case FD_READ: //-----②資料傳送來
{
char cbuf[256];
memset(cbuf,0,256);
int cRecv=recv(ss,cbuf,256,0);
if ((cRecv==SOCKET_ERROR&& WSAGetLastError() == WSAECONNRESET)|| cRecv==0)
{
MessageBox(hwnd,"呼叫recv()失敗!","標題欄提示",MB_OK);
closesocket(ss);
}
else if (cRecv>0)
{
MessageBox(hwnd,cbuf,"收到的資訊",MB_OK);
char Sbuf[]="Hello client!I am server";
int isend=send(ss,Sbuf,sizeof(Sbuf),0);
if (isend==SOCKET_ERROR || isend<=0)
{
MessageBox(hwnd,"傳送訊息失敗!","標題欄提示",MB_OK);
}
else
MessageBox(hwnd,"已經發資訊到客戶端!","標題欄提示",MB_OK);
}
}break;
case FD_CLOSE: //----③關閉連線
{
closesocket(ss);
}
break;
}
}
break;
case WM_CLOSE:
if (IDYES==MessageBox(hwnd,"是否確定退出?","message",MB_YESNO))
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}