从别人那里看到的一篇关于select模型开发的文章,不一定好用,但先留下。
来源:互联网 发布:淘宝推广软件免费的 编辑:程序博客网 时间:2024/05/01 14:11
一、客户端
1。初始化连接即启动连接
if (iError = WSAStartup (MAKEWORD(2,0), &WSAData))//
{
TRACE1(TEXT("Startup error #%i./r/n"),iError);
return false;
}
{
TRACE1(TEXT("Startup error #%i./r/n"),iError);
return false;
}
2。m_gCnSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建一个socket
3。if(SOCKET_ERROR==WSAAsyncSelect(m_gCnSocket,m_hWnd,WM_SOCKET_NOTIFY,
FD_WRITE|FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE))//注册网络异步事件,m_hWnd为应用程序的主对话框或主窗口的句柄
{
TRACE1(TEXT("WSAAsyncSelect error #%i./r/n"),WSAGetLastError());
closesocket(m_gCnSocket);
// WSACleanup();
return false;
}
FD_WRITE|FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE))//注册网络异步事件,m_hWnd为应用程序的主对话框或主窗口的句柄
{
TRACE1(TEXT("WSAAsyncSelect error #%i./r/n"),WSAGetLastError());
closesocket(m_gCnSocket);
// WSACleanup();
return false;
}
4。 向服务端发送连接请求
sa.sin_family = AF_INET;
sa.sin_port = htons(atoi(connectPort));
sa.sin_addr.S_un.S_addr = inet_addr(connectIP);
sa.sin_port = htons(atoi(connectPort));
sa.sin_addr.S_un.S_addr = inet_addr(connectIP);
int iRetErr=connect(m_gCnSocket,(SOCKADDR *)&sa,sizeof(sa));
5。在 stdafx.h 中加入 #define WM_SOCKET_NOTIFY WM_USER + 101
6.下面中加入如下一行
BEGIN_MESSAGE_MAP(CECAS3to5Dlg, CDialog)
//{{AFX_MSG_MAP(CECAS3to5Dlg)
...............
ON_MESSAGE(WM_SOCKET_NOTIFY,OnMyMessage)
...............
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(CECAS3to5Dlg, CDialog)
//{{AFX_MSG_MAP(CECAS3to5Dlg)
...............
ON_MESSAGE(WM_SOCKET_NOTIFY,OnMyMessage)
...............
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
7.在这个项目的构造函数在加入最后的一行
......................
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
.....................
8。下面是自己定义的网络异步事件
LRESULT Class::OnMyMessage(WPARAM wParam,LPARAM lParam)//定义网络事件的响应函数
{
char szMsg[256]="";
int byteReceived;
SYSTEMTIME tm;
char buf[20]="";
char szRecvBuf[512];
if ((DWORD)wParam == (DWORD)m_gCnSocket )
{
switch WSAGETSELECTEVENT(lParam)//调用API函数,得到网络事件类型
{
case FD_CONNECT://发送连接请求后,服务器返回的结果,连接成功或者不成功
if (WSAGETSELECTERROR(lParam) != 0)
//提取错误时没的错误即WSAGETSELECTERROR(lParam)==0
{
closesocket(m_gCnSocket);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str="连接不成功!";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
SetTimer(2,3000,NULL); //定时器用来再连接不成功时重连接服务器
}
else
{
KillTimer(2);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "连接服务器成功.";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
SetTimer(1,time,NULL); //一个1秒一次的定时器,这个里面处理要做的事向服务器发包
//进入程序真正要做的工作
}
break;
case FD_ACCEPT:
break;
case FD_READ://接收包消息发生时接收包
{
memset(szRecvBuf,0,sizeof(szRecvBuf));//清空收包缓存,
byteReceived=recv(wParam,szRecvBuf,sizeof(szRecvBuf),0);//接收包
if (byteReceived==SOCKET_ERROR)
{
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "在接收包时错误!";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
break;
}
else
{
/* char buff[200]="";
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "收包";
{
// m_list2.InsertItem(ii,(LPCTSTR)(_bstr_t)buf);
// m_list2.SetItemText(ii,1,(LPCTSTR)(_bstr_t)str);
// m_list2.SetItemText(ii,2,(LPCTSTR)(_bstr_t)"1111");
// ii++;
}
m_list2.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
//此处做从服务器端收包成功后的处理
*/
}
break;
}
case FD_WRITE:
break;
case FD_CLOSE:
{
KillTimer(1);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "服务器主动关闭Socket!";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
closesocket(m_gCnSocket);
SetTimer(2,3000,NULL);
break;
}
}
}
return 0;
}
char szMsg[256]="";
int byteReceived;
SYSTEMTIME tm;
char buf[20]="";
char szRecvBuf[512];
if ((DWORD)wParam == (DWORD)m_gCnSocket )
{
switch WSAGETSELECTEVENT(lParam)//调用API函数,得到网络事件类型
{
case FD_CONNECT://发送连接请求后,服务器返回的结果,连接成功或者不成功
if (WSAGETSELECTERROR(lParam) != 0)
//提取错误时没的错误即WSAGETSELECTERROR(lParam)==0
{
closesocket(m_gCnSocket);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str="连接不成功!";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
SetTimer(2,3000,NULL); //定时器用来再连接不成功时重连接服务器
}
else
{
KillTimer(2);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "连接服务器成功.";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
SetTimer(1,time,NULL); //一个1秒一次的定时器,这个里面处理要做的事向服务器发包
//进入程序真正要做的工作
}
break;
case FD_ACCEPT:
break;
case FD_READ://接收包消息发生时接收包
{
memset(szRecvBuf,0,sizeof(szRecvBuf));//清空收包缓存,
byteReceived=recv(wParam,szRecvBuf,sizeof(szRecvBuf),0);//接收包
if (byteReceived==SOCKET_ERROR)
{
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "在接收包时错误!";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
break;
}
else
{
/* char buff[200]="";
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "收包";
{
// m_list2.InsertItem(ii,(LPCTSTR)(_bstr_t)buf);
// m_list2.SetItemText(ii,1,(LPCTSTR)(_bstr_t)str);
// m_list2.SetItemText(ii,2,(LPCTSTR)(_bstr_t)"1111");
// ii++;
}
m_list2.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
//此处做从服务器端收包成功后的处理
*/
}
break;
}
case FD_WRITE:
break;
case FD_CLOSE:
{
KillTimer(1);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",
tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
CString str = "服务器主动关闭Socket!";
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(LPCTSTR)(_bstr_t)str);
iii++;
m_list3.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);//滚动条总是在最近的记录处
closesocket(m_gCnSocket);
SetTimer(2,3000,NULL);
break;
}
}
}
return 0;
}
二。服务器端
1。初始化连接即启动连接
if (iError = WSAStartup (MAKEWORD(2,0), &WSAData))//
{
TRACE1(TEXT("Startup error #%i./r/n"),iError);
return false;
}
{
TRACE1(TEXT("Startup error #%i./r/n"),iError);
return false;
}
2。m_gCnSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建一个socket
3。if(SOCKET_ERROR==WSAAsyncSelect(m_gCnSocket,m_hWnd,WM_SOCKET_NOTIFY,
FD_WRITE|FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE))//注册网络异步事件,m_hWnd为应用程序的主对话框或主窗口的句柄
{
TRACE1(TEXT("WSAAsyncSelect error #%i./r/n"),WSAGetLastError());
closesocket(m_gCnSocket);
// WSACleanup();
return false;
}
FD_WRITE|FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE))//注册网络异步事件,m_hWnd为应用程序的主对话框或主窗口的句柄
{
TRACE1(TEXT("WSAAsyncSelect error #%i./r/n"),WSAGetLastError());
closesocket(m_gCnSocket);
// WSACleanup();
return false;
}
4。绑定指定端口
sa.sin_family = AF_INET;
sa.sin_port = htons(server_port);
sa.sin_addr.S_un.S_addr = INADDR_ANY;//inet_addr(szFmIP); //INADDR_ANY;szFmIP //inet_addr(szIPaddress);
int iRetErr;
if ((iRetErr=bind(gsocketEcas,(SOCKADDR *)&sa,sizeof(sa)))<0)
{
closesocket(gsocketEcas);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",tm.wYear,
tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(T("Bind失败."));
sa.sin_port = htons(server_port);
sa.sin_addr.S_un.S_addr = INADDR_ANY;//inet_addr(szFmIP); //INADDR_ANY;szFmIP //inet_addr(szIPaddress);
int iRetErr;
if ((iRetErr=bind(gsocketEcas,(SOCKADDR *)&sa,sizeof(sa)))<0)
{
closesocket(gsocketEcas);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",tm.wYear,
tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(T("Bind失败."));
iii++;
return false;
}
return false;
}
5.侦听此端口
if (listen(gsocketEcas,20)<0)
{
closesocket(gsocketEcas);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",tm.wYear,
tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(T("Listen失败."));
iii++;
return false;
}
{
closesocket(gsocketEcas);
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",tm.wYear,
tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
m_list3.InsertItem(iii,(LPCTSTR)(_bstr_t)buf);
m_list3.SetItemText(iii,1,(T("Listen失败."));
iii++;
return false;
}
6。在 stdafx.h 中加入 #define WM_SOCKET_NOTIFY WM_USER + 101
7.下面中加入如下一行
BEGIN_MESSAGE_MAP(CECAS3to5Dlg, CDialog)
//{{AFX_MSG_MAP(CECAS3to5Dlg)
...............
ON_MESSAGE(WM_SOCKET_NOTIFY,OnMyMessage)
...............
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(CECAS3to5Dlg, CDialog)
//{{AFX_MSG_MAP(CECAS3to5Dlg)
...............
ON_MESSAGE(WM_SOCKET_NOTIFY,OnMyMessage)
...............
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
8.在这个项目的构造函数在加入最后的一行
......................
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
.....................
LRESULT Class::OnMyMessage(WPARAM wParam,LPARAM lParam)//定义网络事件的响应函数
{
CString m_strHostIP;
char szRecvData[512];
SYSTEMTIME tm;
int i;
char buf[20];
struct sockaddr_in addr;
int addrlen = sizeof(addr);
switch WSAGETSELECTEVENT(lParam)
{
case FD_CONNECT://针对客户端连接服务器端后服务器端发回的连接结果,成功与否
if (WSAGETSELECTERROR(lParam) != 0)
{
................
}
else
{
..............
}
break;
case FD_ACCEPT://针对服务器端接收到客户端的连接请求后服务器端的处理
for (i=0;i<MaxQSize;i++)
{
if (m_gSocketEcas[gsocketcount]>0)
gsocketcount=(gsocketcount+1)%MaxQSize;
else
break;
}
m_gSocketEcas[gsocketcount]=accept(wParam,(sockaddr*)&addr,&addrlen);
gsocketcount=(gsocketcount+1)%MaxQSize;
break;
case FD_READ:
{
memset(szRecvData,0,sizeof(szRecvData));
//According to the socket,Get oppisize computer IP Address.
m_strHostIP.Empty();
m_strHostIP=GetHostName(wParam);
int byteReceived=recv(wParam,szRecvData,sizeof(szRecvData),0);
if (byteReceived==SOCKET_ERROR)
{
break;
}
//收到的包内容和IP一一对应的进队列,等待处理
//Add the receive data to a Queue
if (((rear+1) % MaxQSize)==front)
{//队列满
break;
}
if (byteReceived>510)
byteReceived=510;
qlist[rear].m_strIP=m_strHostIP;
memset(qlist[rear].m_Buffer,0,sizeof(qlist[rear].m_Buffer));
memcpy(qlist[rear].m_Buffer,szRecvData,byteReceived);
rear = (rear+1) % MaxQSize;
break;
}
case FD_WRITE:
break;
case FD_CLOSE://服务端或者客户端关闭连接后的处理
/* if (wParam==gsockHkGw)
{
closesocket(gsockHkGw);
gbHkGwConFlag=false;
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",tm.wYear,
tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
}
*/
for (i=0;i<MaxQSize;i++)
{
if (m_gSocketEcas[i]==wParam)
{
// closesocket(m_gSocketEcas[i]);
m_gSocketEcas[i]=0;
}
}
shutdown(wParam,SD_BOTH);
closesocket(wParam);
break;
}
return 0;
char szRecvData[512];
SYSTEMTIME tm;
int i;
char buf[20];
struct sockaddr_in addr;
int addrlen = sizeof(addr);
switch WSAGETSELECTEVENT(lParam)
{
case FD_CONNECT://针对客户端连接服务器端后服务器端发回的连接结果,成功与否
if (WSAGETSELECTERROR(lParam) != 0)
{
................
}
else
{
..............
}
break;
case FD_ACCEPT://针对服务器端接收到客户端的连接请求后服务器端的处理
for (i=0;i<MaxQSize;i++)
{
if (m_gSocketEcas[gsocketcount]>0)
gsocketcount=(gsocketcount+1)%MaxQSize;
else
break;
}
m_gSocketEcas[gsocketcount]=accept(wParam,(sockaddr*)&addr,&addrlen);
gsocketcount=(gsocketcount+1)%MaxQSize;
break;
case FD_READ:
{
memset(szRecvData,0,sizeof(szRecvData));
//According to the socket,Get oppisize computer IP Address.
m_strHostIP.Empty();
m_strHostIP=GetHostName(wParam);
int byteReceived=recv(wParam,szRecvData,sizeof(szRecvData),0);
if (byteReceived==SOCKET_ERROR)
{
break;
}
//收到的包内容和IP一一对应的进队列,等待处理
//Add the receive data to a Queue
if (((rear+1) % MaxQSize)==front)
{//队列满
break;
}
if (byteReceived>510)
byteReceived=510;
qlist[rear].m_strIP=m_strHostIP;
memset(qlist[rear].m_Buffer,0,sizeof(qlist[rear].m_Buffer));
memcpy(qlist[rear].m_Buffer,szRecvData,byteReceived);
rear = (rear+1) % MaxQSize;
break;
}
case FD_WRITE:
break;
case FD_CLOSE://服务端或者客户端关闭连接后的处理
/* if (wParam==gsockHkGw)
{
closesocket(gsockHkGw);
gbHkGwConFlag=false;
GetLocalTime(&tm);
sprintf(buf,"%04d-%02d-%02d %02d:%02d:%02d",tm.wYear,
tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
}
*/
for (i=0;i<MaxQSize;i++)
{
if (m_gSocketEcas[i]==wParam)
{
// closesocket(m_gSocketEcas[i]);
m_gSocketEcas[i]=0;
}
}
shutdown(wParam,SD_BOTH);
closesocket(wParam);
break;
}
return 0;
}
- 从别人那里看到的一篇关于select模型开发的文章,不一定好用,但先留下。
- 看到一篇串口的好文章
- 转一篇关于linux设备模型的好文章
- 看到的一篇文章
- 看到的一篇讲js比较好的文章,关于function
- 从别人那里转过来的几篇讲解WSDL WEBSERVICE 的文章,感觉挺好的
- 看到的好文章
- 看到的一篇介绍strncpy()函数比较好的文章
- 看到一篇好的文章计算机专业的学习心得
- 看到的一篇介绍strncpy()函数比较好的文章
- 看到一篇Java学习的好文章,适合初学者!
- 看到一篇关于上传文章,先抄过来,慢慢学习
- 前几天看到的一篇文章
- 看到一篇不错的文章
- 最近看到的一篇文章
- 看到一篇很好的文章
- 网上看到的一篇文章
- 看到一篇关于如何养成一个良好的 Android 开发习惯文章,感觉不错
- Hex Workshop v5.0.2.2769 Incl.Keymaker-EMBRACE
- 附魔材料分解向导
- 拓普是什么意思
- 常用正则表达式
- test
- 从别人那里看到的一篇关于select模型开发的文章,不一定好用,但先留下。
- 副本推荐等级
- 21天学通C#的重要点
- 原来世界上不是只有魔兽世界一个游戏
- .NET编程中的27个基础函数集(转载)
- 全面深入介绍C++字符串:string类
- 不要迷失在技术的海洋中(转载)
- 内联函数与宏定义
- c/c++程序的内存分配