// select_selfDlg.h : 头文件
//
#pragma once
#include "CInitSock.h"
#include <list>
#include "afxwin.h"
using namespace std;
#define THREAD_NUM 2
// Cselect_selfDlg 对话框
class Cselect_selfDlg : public CDialog
{
// 构造
public:
Cselect_selfDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_SELECT_SELF_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
static DWORD WINAPI ListenThreadFun(LPVOID lpParam);
static DWORD WINAPI ClientThreadFun(LPVOID lpParam);
HANDLE handleArray[THREAD_NUM];
void showMessage(CString & szinfo);
CInitSock m_InitSock;
SOCKET m_sockListen;
HANDLE handleEvent;
list<SOCKET> m_vecSockClient;
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnClose();
CEdit m_Edit;
};
以下是主要几个线程函数
void Cselect_selfDlg::OnBnClickedButton1()
{
handleEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
handleArray[0] = CreateThread(NULL,0,ListenThreadFun,this,NULL,NULL);
handleArray[1] = CreateThread(NULL,0,ClientThreadFun,this,NULL,NULL);
}
DWORD WINAPI Cselect_selfDlg::ListenThreadFun(LPVOID lpParam)
{
Cselect_selfDlg * pThis = (Cselect_selfDlg *)lpParam;
pThis->m_sockListen = socket(AF_INET,SOCK_STREAM,0);
if(pThis->m_sockListen == INVALID_SOCKET)
{
AfxMessageBox(_T("创建套接字失败!"));
return 0;
}
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(4567);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
bind(pThis->m_sockListen,(sockaddr*)&sin,sizeof(sin));
listen(pThis->m_sockListen,5);
while(TRUE)
{
//WaitForSingleObject(pThis->handleEvent,INFINITE);
sockaddr_in addRemote;
int nLen = sizeof(addRemote);
SOCKET sockaccept = INVALID_SOCKET;
sockaccept = accept(pThis->m_sockListen,(sockaddr*)&addRemote,&nLen);
if(sockaccept == INVALID_SOCKET)
continue;
CString szIpInfo = Multi2WideChar(inet_ntoa(addRemote.sin_addr));
pThis->showMessage(szIpInfo);
// if(pThis->m_vecSockClient.size() > 64)
// {
// send(*sockaccept,"too much client",20,0);
// closesocket(*sockaccept);
// delete sockaccept;
// continue;
// }
pThis->m_vecSockClient.push_back(sockaccept);
// SetEvent(pThis->handleEvent);
}
return 0;
}
DWORD WINAPI Cselect_selfDlg::ClientThreadFun(LPVOID lpParam)
{
Cselect_selfDlg * pThis = (Cselect_selfDlg*)lpParam;
fd_set fdset;
while(TRUE)
{
//WaitForSingleObject(pThis->handleEvent,INFINITE);
Sleep(100);
FD_ZERO(&fdset);
if(pThis->m_vecSockClient.empty())
continue;
list<SOCKET>::iterator iter;
for(iter = pThis->m_vecSockClient.begin(); iter != pThis->m_vecSockClient.end(); ++ iter)
{
FD_SET(*iter,&fdset);
}
timeval tv = {1,0};
int nRet = select(0,&fdset,NULL,NULL,&tv);
if(nRet > 0)
{
//for(int i = 0; i < pThis->m_vecSockClient.size(); i ++)
for(iter = pThis->m_vecSockClient.begin();iter != pThis->m_vecSockClient.end();)
{
if(FD_ISSET(*iter,&fdset))
{
TCHAR szBuf[200] = {0};
int nRev = recv(*iter,(char*)szBuf,200,0);
if(nRev > 0)
{
CString strtemp = szBuf;
pThis->showMessage(strtemp);
iter++;
}
else
{
closesocket(*iter);
FD_CLR(*iter,&fdset);
//delete *iter;
iter = pThis->m_vecSockClient.erase(iter);
}
}
else
iter ++;
}
}
}
return 0;
}