WSAAyncSelect 学习的经典例子(tcp实现)

/*
WSAAyncSelect server 代码
*/
#include "stdafx.h"
#define WM_SOCKET WM_USER+101 
#include <WINSOCK2.H> 
#include "stdafx.h"
#include <winsock.h>
#include <iostream>
using namespace std;
#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 nShowCmd)
{
	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 = TEXT("Test");
	//---注册窗口类---- 
	RegisterClass(&wc);
	//---创建窗口---- 
	HWND hwnd = CreateWindow(TEXT("Test"), TEXT("窗口标题"), WS_SYSMENU, 300, 0, 600, 400, NULL, NULL, hInstance, NULL);
	if (hwnd == NULL)
	{
		MessageBox(hwnd, TEXT("创建窗口出错"), TEXT("标题栏提升"), 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, TEXT("WSAStartup() Failed"), TEXT("调用失败"), 0);
		return 1;
	}
	SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == INVALID_SOCKET)
	{
		MessageBox(NULL, TEXT("socket() Failed"), TEXT("调用失败"), 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("127.0.0.1");
	if (bind(s, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		MessageBox(NULL, TEXT("bind() Failed"), TEXT("调用失败"), 0);
		return 1;
	}
	if (listen(s, 3) == SOCKET_ERROR)
	{
		MessageBox(NULL, TEXT("listen() Failed"), TEXT("调用失败"), 0);
		return 1;
	}
	else
		MessageBox(NULL, TEXT("waiting meg4"), TEXT("调用失败"), 0);
		//cout << "waiting meg4" << endl;
		MessageBox(hwnd, TEXT("进入监听状态!"), TEXT("标题栏提示"), MB_OK);
	  /*
    int WSAAsyncSelect(
    SOCKET s,  //标识一个需要事件通知的套接口描述符
    HWND hWnd,  //标识一个在网络事件发生时要想收到消息的窗口或对话框的句柄
    u_int wMsg,  //在网络事件发生时要接收的消息,该消息会投递到由hWnd句柄指定的窗口或对话框
    long lEvent  //位屏蔽码,用于指明应用程序感兴趣的网络事件集合
    );
    */
    //---消息循环---- 
    MSG msg; 
    while (GetMessage(&msg,0,0,0)) 
    { 
        TranslateMessage(&msg); //将键盘上的虚拟消息进行映射成系统消息,放到消息队列中
        DispatchMessage(&msg); 
        /*
        它的意思就是说要把这条消息发送到窗口里的消息处理函数WindowProc
        */
    } 
	closesocket(s);
	WSACleanup();
	return msg.wParam;
}
//-------------------窗口过程---------------------- 
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		cout << "waiting meg5" << endl;

	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, TEXT("调用accept()失败!"), TEXT("标题栏提示"), 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, TEXT("调用recv()失败!"), TEXT("标题栏提示"), MB_OK);
											  closesocket(ss);
										  }
										  else if (cRecv>0)
										  {
											  MessageBox(hwnd, (LPCWSTR)cbuf, TEXT("收到的信息"), 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, TEXT("发送消息失败!"), TEXT("标题栏提示"), MB_OK);
											  }
											  else
												  MessageBox(hwnd, TEXT("已经发信息到客户端!"), TEXT("标题栏提示"), MB_OK);
										  }
					  }break;
					  case FD_CLOSE:    //----③关闭连接 
					  {
											closesocket(ss);
					  }
						  break;
					  }
	}
		break;
	case WM_CLOSE:
		if (IDYES == MessageBox(hwnd, TEXT("是否确定退出?"), TEXT("message"), MB_YESNO))
			DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, uMsg, wParam, lParam);
	}
	return 0;
}



/*
WSAAyncSelect client 代码

*/
#include "stdafx.h"
#include <iostream>
using namespace std;
//#include <WINSOCK2.H>
#include < WinSock2.h> 
#pragma comment( lib, "ws2_32" ) 
#include < stdio.h> 
int main()
{
	system("chcp 936>NUL");
	printf("1号客户端程序\n");
	//-----------①加载----------------
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		printf("WSAStartup Failed,Error=【%d】\n", WSAGetLastError());
		return 1;
	}
	else
		printf("①加载成功\n");
	//-------------②创建流式套接字-----------------
	SOCKET c1 = socket(AF_INET, SOCK_STREAM, 0);
	if (c1 == INVALID_SOCKET)
	{
		printf("socket() Failed,Error=【%d】\n", WSAGetLastError());
		return 1;
	}
	else
		printf("②已创建连接套接字:【%d】\n", c1);

	//------------③连接请求---------------
	struct sockaddr_in Sadd;
	Sadd.sin_family = AF_INET;
	Sadd.sin_port = htons(1111);
	Sadd.sin_addr.s_addr = inet_addr("127.0.0.1");     if (connect(c1, (sockaddr*)& Sadd, sizeof (Sadd)) == -1)
	{
		printf("Failed connect(),Error=【%d】\n", WSAGetLastError());
		return 1;
	}
	else //*********连接成功,可以开始发送、接收************
	{
		printf("③连接成功,服务器IP地址:【%s】,端口号:【%d】\n", inet_ntoa(Sadd.sin_addr), ntohs(Sadd.sin_port));
		int a;
		printf("希望发送数据吗?(键入“1”发送,键入其他值则退出)");
		scanf("%d", &a);
		while (a == 1)
		{
			//---发送-----
			char S_buf[] = "Hello!I am a client 1";
			int isend = send(c1, S_buf, strlen(S_buf), 0);
			if (isend == SOCKET_ERROR)
			{
				printf("Failed send(),Error=【%d】,或者服务器意外关闭\n", WSAGetLastError());
				return 1;
			}
			else if (isend != 0)
				printf("信息【%s】已发送\n", S_buf);
			else
				printf("信息无法发送给客户端\n");
			//---接收----
			char R_buf[256];
			int RRecv;
			memset(R_buf, 0, sizeof (R_buf));
			RRecv = recv(c1, R_buf, 256, 0);
			if (RRecv == SOCKET_ERROR)
			{
				printf("Failed recv(),Error=【%d】\n", WSAGetLastError());
				return 1;
			}
			else if (RRecv == 0)
				printf("无法收到来自服务器的任何数据,或者服务器意外关闭\n");
			else
			{
				printf("接收到来自服务器的数据:【%s】\n", R_buf);
				printf("希望继续发送数据吗?(键入”1“继续发送,键入其他值则退出)");
				scanf("%d", &a);
				if (a != 1)
					break;
			}
		} //-------end 结束
		printf("已选择退出连接\n");
	} //------end 结束
	//-------------------④关闭、释放------------
	closesocket(c1);
	WSACleanup();
	printf("④与服务器连接完毕\n");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值