您的位置:首页 > 其它

socket 的select函数例子

2015-09-18 16:20 309 查看
好久没有写博客了,主要最近也没有学啥新的可以写博客的东西

select函数是通过设置FD_SET来实现在一个线程中实现读写网口的,下面这段代码主要是实现绑定端口-》监听-》设置socket为非阻塞-》读取网口-》回写网口的。缺点是只能有一个socket连接,优点是代码简单,便于入门。在这里鄙视一下 《socket编程之select()》的博主,写个代码还故意整点bug,不过他写的文字还是很好的,可以配合下面的代码看看,不过代码不是他的哦。

#include <WINSOCK2.H>
#include <iostream>

#pragma comment(lib,"WS2_32.lib")

#define PORT 8080
#define DATA_BUFSIZE 8192
char recvBuffer[DATA_BUFSIZE];
//目标是一个客户端可以连接

int main()
{
SOCKET ListenSocket; // 监听套接字
SOCKET AcceptSocket; // 与客户端进行通信的套接字
SOCKADDR_IN InternetAddr; // 服务器的地址
WSADATA wsaData; // 用于初始化套接字环境
INT Ret; // WinSock API的返回值
FD_SET WriteSet; // 获取可写性的套接字集合
FD_SET ReadSet; // 获取可读性的套接字集合
DWORD Total = 0; // 处于就绪状态的套接字数量
DWORD SendBytes; // 发送的字节数
DWORD RecvBytes; // 接收的字节数

bool bSocketInit = false;//socket是否初始化过

// 初始化WinSock环境
if ((Ret = WSAStartup(0x0202,&wsaData)) != 0)
{
printf("WSAStartup() failed with error %d\n", Ret);
WSACleanup();
return -1;
}
ListenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(PORT);
//绑定
if(bind(ListenSocket, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return -1;
}
//监听
listen(ListenSocket,1);
//设置费阻塞
u_long noneBlock = 1 ;
ioctlsocket(ListenSocket,FIONBIO,&noneBlock);
int recvLen = 0;
while(true)
{
//清空
FD_ZERO(&ReadSet);
FD_ZERO(&WriteSet);

//指定listensocket可以读
FD_SET(ListenSocket,&ReadSet);

if(bSocketInit)
{
FD_SET(AcceptSocket,&ReadSet);//注意,就只能连接一个,因为这样代码简单
FD_SET(AcceptSocket,&WriteSet);
}

//循环调用select函数
select(1,&ReadSet,&WriteSet,NULL,NULL);//不检测错误信息,不阻塞

//判断有没有新的socket连接
if(FD_ISSET(ListenSocket,&ReadSet))
{
AcceptSocket = accept(ListenSocket,NULL,NULL);
//设置新来的socket为非阻塞
ioctlsocket(AcceptSocket,FIONBIO,&noneBlock);
bSocketInit = true;//就能连接一个
}
//判断新的socket
if(bSocketInit)
{
if(FD_ISSET(AcceptSocket,&ReadSet)){
//接受数据
int len = recv(AcceptSocket,recvBuffer,DATA_BUFSIZE,0);
if(len>0){
recvLen = len;
}else{
//客户端关闭了
bSocketInit = false;
closesocket(AcceptSocket);
len = 0;
recvLen = 0;
}
}
if(FD_ISSET(AcceptSocket,&WriteSet))
{
//
if(recvLen>0)
{
if( send(AcceptSocket,recvBuffer,recvLen,0)
!= SOCKET_ERROR)
{
recvLen = 0;
printf(recvBuffer);
}
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: