VC中TCP实现 异步套接字编程的原理+代码
所谓的异步套接字编程就是 调用了 如下函数
WSAAsyncSelect 设置了 套接字的状态为异步,有关函数我会在下面详细介绍。。。
异步套接字解决了 套接字编程过程中的堵塞问题 ...... 什么是堵塞?请看下面
你可能有过这样的体会 在 VC编写基于界面的网路程序时候 ,调用 recv recvfrom accept 等函数的时候 整个程序的主线程进入堵塞状态直到 有连接或者信息的到来。 我们可以利用多线程的方法解决主线程堵塞的问题,但是我们如果一个程序需要多个套接字 那么 就需要创建多个线程,线程创建多了回会导致一些不必要的麻烦 和操作上的不便。 我们利用非堵塞套接字可以解决这个问题 ,现在明白了吧 ,下面我讲讲述异步套接字实现 客户端服务端的通信 代码我会传到CSDN 大家可以去下载。。。。
当一个连接到来得时候 我这里假设是 基于TCP的服务器端 那么我要accept 一直等待 ,但是在异步套接字中 这个等待被转移了 。。我们吧acept放倒一个消息响应中来调用 只有 当某种我们希望的条件发生的时候才会调用accept 那么这里就是 只有 客户端connect 的时候才会调用accept 这样的话线程 永远不会堵塞 。
可能这样说的还有些模糊 下面 是一个TCP服务器端的 编写顺序 :
1 、首先加载套接字库 和包含必要的文件
#include "winsock2.h"
#pragma comment(lib,"ws2_32.lib")
2、加载套接字库 对服务器端和客户端 库版本要一直 我们这里是2.0的 套接字版本
WSADATA wsa ;
WSAStartup(MAKEWORD(2,0),&wsa) ;
3 、创建套接字 并且利用 WSAAsyncSelect 设置为异步套接字 并且有网络事件发生的时候会发出 WM_SOCKET消息( 我们自定义的消息)
#deinfe WM_SOCKET WM_USER+1 ,对应的消息响应 要自己添加 不会下载我给的源代码
int WSAAsyncSelect(
SOCKET s, //socket
HWND hWnd, //要发送消息的窗体 hwnd
unsigned int wMsg, //WM_SOCKET
long lEvent ,//注意这个就是我们需要的网络事件具体看MSDN 我们一般只用到 FD_READ FD_ACCEPT 就是网络读取事件 和网络连接事件
);
4. 配置地址结构体SOCKADDR_IN 和调用bind绑定地址 结构体 然后调用 listen监听 *(一定要在listen之前调用bind)
完成之后我们不用accept了 因为 这个需要我们在 消息响应函数 里面 来调用 因为我们感兴趣的 网络事件可能有多种那么 我们需要 在消息响应函数
用一个switch循环来判断是哪个网络事件 部分代码如下:
void CSynSocketSrvDlg::OnConnect(WPARAM wParam ,LPARAM lParam)
{
switch(lParam)
{
case FD_ACCEPT:
{
SOCKADDR addr ;
int len;
len=sizeof(SOCKADDR) ;
GetDlgItem(IDC_EDIT1)->SetWindowText("新的连接到来....\n") ;
tem=::accept(m_socket,(SOCKADDR*)&addr,&len) ;
break ;
}
case FD_READ:
{
char buf[100] ="";
recv(tem,buf,100,0) ;
GetDlgItem(IDC_EDIT1)->SetWindowText(buf) ;
break ;
}
}
}
客户端
1 、首先加载套接字库 和包含必要的文件
#include "winsock2.h"
#pragma comment(lib,"ws2_32.lib")
2、加载套接字库 对服务器端和客户端 库版本要一直 我们这里是2.0的 套接字版本
WSADATA wsa ;
WSAStartup(MAKEWORD(2,0),&wsa) ;
3 、创建套接字 并且利用 WSAAsyncSelect 设置为异步套接字 并且有网络事件发生的时候会发出 WM_SOCKET消息( 我们自定义的消息)
#deinfe WM_SOCKET WM_USER+1 ,对应的消息响应 要自己添加 不会下载我给的源代码
int WSAAsyncSelect(
SOCKET s, //socket
HWND hWnd, //要发送消息的窗体 hwnd
unsigned int wMsg, //WM_SOCKET
long lEvent ,//注意这个就是我们需要的网络事件具体看MSDN 我们一般只用到 FD_READ 就是网络读取事件 );
4、 然后我们可以发送数据了 发送是 send
接收消息和服务端一样在 消息响应函数里面实现
代码下载地址
http://download.csdn.net/detail/yue7603835/3771590