c++学习之路-----------------线程同步与异步套接字编程

1.



2  事件同步

#include <windows.h>
#include <iostream.h>

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
);

DWORD WINAPI Fun2Proc(
  LPVOID lpParameter   // thread data
);

int tickets=100;
HANDLE g_hEvent;

void main()
{
	HANDLE hThread1;
	HANDLE hThread2;
	hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
	hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
	CloseHandle(hThread1);
	CloseHandle(hThread2);

	//g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
	g_hEvent=CreateEvent(NULL,FALSE,FALSE,"tickets");
	if(g_hEvent)
	{
		if(ERROR_ALREADY_EXISTS==GetLastError())
		{
			cout<<"only instance can run!"<<endl;
			return;
		}
	}
	SetEvent(g_hEvent);

	Sleep(4000);
	CloseHandle(g_hEvent);
}

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
)
{
	while(TRUE)
	{
		WaitForSingleObject(g_hEvent,INFINITE);
//		ResetEvent(g_hEvent);
		if(tickets>0)
		{
			Sleep(1);
			cout<<"thread1 sell ticket : "<<tickets--<<endl;
		}
		else
			break;
		SetEvent(g_hEvent);
	}
	
	return 0;
}

DWORD WINAPI Fun2Proc(
  LPVOID lpParameter   // thread data
)
{
	
	while(TRUE)
	{
		WaitForSingleObject(g_hEvent,INFINITE);
//		ResetEvent(g_hEvent);
		if(tickets>0)
		{
			Sleep(1);
			cout<<"thread2 sell ticket : "<<tickets--<<endl;
		}
		else
			break;
		SetEvent(g_hEvent);
	}
	
	return 0;
}

3  异步套接字




4


5  采用socket2.2版本,所以使用WSAStartup,msdn里有例子

Requirements

  Windows NT/2000/XP: Included in Windows NT 3.1 and later.
  Windows 95/98/Me: Included in Windows 95 and later.
  Header: Declared in Winsock2.h.
  Library: Use Ws2_32.lib.


WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	
	wVersionRequested = MAKEWORD( 2, 2 );
	
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
	
		return FALSE;
	}
	

	if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) {

		WSACleanup( );
		return FALSE; 
	}

6.   初始化socket

BOOL CChatDlg::InitSocket()
{
	m_socket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,0);
	if(INVALID_SOCKET==m_socket)
	{
		MessageBox("创建套接字失败!");
		return FALSE;
	}
	SOCKADDR_IN addrSock;
	addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	addrSock.sin_family=AF_INET;
	addrSock.sin_port=htons(6000);
	if(SOCKET_ERROR==bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR)))
	{
		MessageBox("绑定失败!");
		return FALSE;
	}
	if(SOCKET_ERROR==WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ))//UM_SOCK为自定义消息
	{
		MessageBox("注册网络读取事件失败!");
		return FALSE;
	}

	return TRUE;
}


7  自定义消息

ChatDlg.h

#define UM_SOCK		WM_USER+1

声明消息响应函数ChatDlg.h中

protected:
	HICON m_hIcon;

	// Generated message map functions
	//{{AFX_MSG(CChatDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg void OnBtnSend();
	//}}AFX_MSG
	afx_msg void OnSock(WPARAM,LPARAM);//自定义消息响应函数在这里写
	DECLARE_MESSAGE_MAP()
private:
	SOCKET m_socket;
};


接下来是消息映射ChatDlg。cpp

BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
	//{{AFX_MSG_MAP(CChatDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_SEND, OnBtnSend)
	//}}AFX_MSG_MAP
	ON_MESSAGE(UM_SOCK,OnSock)
END_MESSAGE_MAP()

自定义消息函数的实现 接受部分

void CChatDlg::OnSock(WPARAM wParam,LPARAM lParam)
{
	switch(LOWORD(lParam))
	{
	case FD_READ:
		WSABUF wsabuf;
		wsabuf.buf=new char[200];
		wsabuf.len=200;
		DWORD dwRead;
		DWORD dwFlag=0;
		SOCKADDR_IN addrFrom;
		int len=sizeof(SOCKADDR);
		CString str;
		CString strTemp;
		HOSTENT *pHost;
		if(SOCKET_ERROR==WSARecvFrom(m_socket,&wsabuf,1,&dwRead,&dwFlag,
						(SOCKADDR*)&addrFrom,&len,NULL,NULL))
		{
			MessageBox("接收数据失败!");
			return;
		}
		pHost=gethostbyaddr((char*)&addrFrom.sin_addr.S_un.S_addr,4,AF_INET);
		//str.Format("%s说 :%s",inet_ntoa(addrFrom.sin_addr),wsabuf.buf);
		str.Format("%s说 :%s",pHost->h_name,wsabuf.buf);
		str+="\r\n";
		GetDlgItemText(IDC_EDIT_RECV,strTemp);
		str+=strTemp;
		SetDlgItemText(IDC_EDIT_RECV,str);
		break;
	}
}

8  发送端

void CChatDlg::OnBtnSend() 
{
	// TODO: Add your control notification handler code here
	DWORD dwIP;
	CString strSend;
	WSABUF wsabuf;
	DWORD dwSend;
	int len;
	CString strHostName;
	SOCKADDR_IN addrTo;
	HOSTENT* pHost;
	if(GetDlgItemText(IDC_EDIT_HOSTNAME,strHostName),strHostName=="")
	{
		((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
		addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
	}
	else
	{
		pHost=gethostbyname(strHostName);
		addrTo.sin_addr.S_un.S_addr=*((DWORD*)pHost->h_addr_list[0]);
	}
	
	addrTo.sin_family=AF_INET;
	addrTo.sin_port=htons(6000);

	GetDlgItemText(IDC_EDIT_SEND,strSend);
	len=strSend.GetLength();
	wsabuf.buf=strSend.GetBuffer(len);
	wsabuf.len=len+1;

	SetDlgItemText(IDC_EDIT_SEND,"");

	if(SOCKET_ERROR==WSASendTo(m_socket,&wsabuf,1,&dwSend,0,
			(SOCKADDR*)&addrTo,sizeof(SOCKADDR),NULL,NULL))
	{
		MessageBox("发送数据失败!");
		return;
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值