非阻塞模式(ioctlsocket)
//Server.cpp
#include <stdio.h>
#include <winsock2.h> //winsock.h (2种套接字版本)
#pragma comment(lib,"ws2_32.lib") //wsock32.lib #define MAXSIZE 100 // int main()
{
//
int retVal; char buf[MAXSIZE]; //初始化套接字库
WORD wVersionRequest;
WSADATA wsadata; wVersionRequest=MAKEWORD(,); retVal=WSAStartup(wVersionRequest,&wsadata);
if(retVal == SOCKET_ERROR)
{
printf("WSAStartup failed!"); return -;
} //创建套接字
SOCKET sServer;
sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sServer == INVALID_SOCKET)
{
printf("socket failed!"); WSACleanup();
return -; //每次检测到失败后,即需要返回
} //设置为非阻塞模式
int imode=;
retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode);
if(retVal == SOCKET_ERROR)
{
printf("ioctlsocket failed!"); closesocket(sServer);
WSACleanup();
return -;
} //绑定套接字并将其设置为监听状态
SOCKADDR_IN addrServ;
addrServ.sin_family=AF_INET;
addrServ.sin_port =htons();
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //绑定套接字到某一个具体的服务器
if(retVal == SOCKET_ERROR)
{
printf("bind failed!"); closesocket(sServer);
WSACleanup();
return -;
} retVal=listen(sServer,); //第二个参数,表示最大连接数目
if(retVal == SOCKET_ERROR)
{
printf("listen failed!"); closesocket(sServer);
WSACleanup();
return -;
} //接受连接
sockaddr_in addrClient; //定义一个临时地址,用于接受连接(注意:某个客户端由Client.cpp确定)
int len=sizeof(sockaddr_in); SOCKET sClient;
int errcode; while(true)
{
sClient=accept(sServer,(sockaddr *)&addrClient,&len);
if(sClient == INVALID_SOCKET)
{
errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //表示没有客户端发起连接,继续循环
{
Sleep();
continue;
}
else
{
printf("accept failed!"); closesocket(sServer); //连接失败,关闭服务器套接字并释放套接字库
WSACleanup(); //
return -;
}
} break; //
} //接收数据
while(true)
{
retVal=recv(sClient,buf,strlen(buf),);
if(retVal == SOCKET_ERROR)
{
errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)
{
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return -;
}
}
} if(buf == "quit") //如果接收数据为"quit",则发送回显"quit"
{
retVal=send(sClient,buf,strlen(buf),);
break;
}
else
{
//发送数据
while(true)
{
retVal=send(sClient,buf,strlen(buf),); //a.回显接收数据;b.第四个参数:0?
if(retVal == SOCKET_ERROR) //错误处理
{
errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return -; }
} break; //如果发送数据成功,则退出循环
} }
} }
//Client.cpp
#include <stdio.h>
#include <WinSock2.h> //winsock.h
#pragma comment(lib,"ws2_32.lib"); //wsock32.lib #include <iostream>
using namespace std; #include <string.h> //strcpy函数 #define MAXSIZE 100 // int main()
{
//
int retVal; char buf[MAXSIZE]; //初始化套接字库
WORD wVersionRequest;
WSADATA wsadata; wVersionRequest=MAKEWORD(,); retVal=WSAStartup(wVersionRequest,&wsadata);
if(retVal == SOCKET_ERROR)
{
printf("WSAStartup failed!"); return -;
} //创建套接字
SOCKET sClient;
sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
printf("socket failed!"); WSACleanup();
return -; //每次检测到失败后,即需要返回
} //设置为非阻塞模式
int imode=;
retVal=ioctlsocket(sClient,FIONBIO,(u_long *)&imode);
if(retVal == SOCKET_ERROR)
{
printf("ioctlsocket failed!"); closesocket(sClient);
WSACleanup();
return -;
} //发起连接
sockaddr_in addrServ;
addrServ.sin_family=AF_INET; //表示使用的是,TCP/IP地址家族
addrServ.sin_port =htons(); //为什么要使用htons宏?
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); int len=sizeof(sockaddr_in); //sizeof只是一个运算符,不是函数 while(true)
{
retVal=connect(sClient,(sockaddr *)&addrServ,len); //连接到某一个具体的服务器
if(retVal == INVALID_SOCKET)
{
int errcode=WSAGetLastError();
if(errcode==WSAEWOULDBLOCK || errcode==WSAEINVAL) //表示服务器端未准备好,继续循环
{
Sleep();
continue;
}
else
{
if(errcode == WSAEISCONN) //连接成功,则退出
{
break;
}
else //否则连接失败,关闭客户端套接字并释放套接字库
{
printf("connect failed!"); closesocket(sClient);
WSACleanup(); //
return -;
}
}
} } //发送数据
while(true)
{
//
//scanf(buf);
//cin>>buf; strcpy(buf,"Hello TCP!"); retVal=send(sClient,buf,strlen(buf),); //a.回显接收数据;b.第四个参数:0?
if(retVal == SOCKET_ERROR) //错误处理
{
int errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
printf("send failed!"); closesocket(sClient);
//closesocket(sServer);
WSACleanup();
return -; }
} break; //如果发送数据成功,则退出循环
} //接收数据
while(true)
{
retVal=recv(sClient,buf,strlen(buf),);
if(retVal == SOCKET_ERROR)
{
int errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)
{
printf("recv failed!"); closesocket(sClient);
//closesocket(sServer);
WSACleanup();
return -;
}
}
} break;
}
}
1.
#include <winsock2.h> //winsock.h (2种套接字版本)
#pragma comment(lib,"ws2_32.lib") //wsock32.lib
2.
retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode); //第3个参数通常设为1(同时第2个参数设为FIONBIO),表示非阻塞模式
3.
a. //绑定套接字并将其设置为监听状态
SOCKADDR_IN addrServ;
addrServ.sin_family=AF_INET;
addrServ.sin_port =htons(5000);
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102");
retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //绑定套接字到某一个具体的服务器
这一段代码表明,bind函数需要定义一个addrServ,并且要为每个字段赋值。
b. retVal=listen(sServer,1); //第二个参数,表示最大连接数目
4.
//接受连接
sockaddr_in addrClient; //定义一个临时地址,用于接受连接(注意:某个客户端由Client.cpp确定)
int len=sizeof(sockaddr_in);
SOCKET sClient;
int errcode;
while(true)
{
sClient=accept(sServer,(sockaddr *)&addrClient,&len);
if(sClient == INVALID_SOCKET)
{
errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //表示没有客户端发起连接,继续循环
{
……
5.
retVal=recv(sClient,buf,strlen(buf),0);//第4个参数,表示影响该函数的行为(通常设为0)
retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0?
------------------------------------------------------------------------------------------------
1.
addrServ.sin_port =htons(5000); //为什么要使用htons宏?前者的字段类型和宏的返回值类型一致
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); //同理,后者函数的返回值类型和字段类型一致
2.
//scanf(buf); //问题①:为何这两个发送字符串我发送不了?
//cin>>buf;
strcpy(buf,"Hello TCP!"); //发送固定字符串
3.
问题②:下次继续做实验,bind failed的原因,而且是Client.cpp端出现的 真奇怪?(自己有调试,结果发现port字段和自己设置的不一致,不知为何)
http://qxzbgzh.blog.51cto.com/blog/2821013/875991
非阻塞模式(ioctlsocket)的更多相关文章
- Socket 阻塞模式和非阻塞模式
阻塞I/O模型: 简介:进程会一直阻塞,直到数据拷贝 完成 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返 ...
- 看到关于socket非阻塞模式设置方式记录一下。
关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的:我打个很简单的比方,如果你调用socket send函数时: 如果是阻塞模式下: send先比较待发送数据的长度len和套接 ...
- 服务器编程心得(四)—— 如何将socket设置为非阻塞模式
1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ ...
- PHP非阻塞模式 (转自 尘缘)
让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_re ...
- TCP同步与异步及阻塞模式,多线程+阻塞模式,非阻塞模式简单介绍
首先我简单介绍一下同步TCP编程 与异步TCP编程. 在服务端我们通常用一个TcpListener来监听一个IP和端口.客户端来一个请求的连接,在服务端可以用同步的方式来接收,也可以用异步的方式去接收 ...
- UDP socket 设置为的非阻塞模式
UDP socket 设置为的非阻塞模式 Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct so ...
- socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto
socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...
- 转:PHP非阻塞模式
你可以任意转摘“PHP非阻塞模式”,但请保留本文出处和版权信息.作者:尘缘,QQ:130775,来源:http://www.4wei.cn/archives/1002336 让PHP不再阻塞当PHP作 ...
- 转:PHP中实现非阻塞模式
原文来自于:http://blog.csdn.net/linvo/article/details/5466046 程序非阻塞模式,这里也可以理解成并发.而并发又暂且可以分为网络请求并发 和本地并发 . ...
随机推荐
- XiangBai——【CVPR2018】Multi-Oriented Scene Text Detection via Corner Localization and Region Segmentation
XiangBai——[CVPR2018]Multi-Oriented Scene Text Detection via Corner Localization and Region Segmentat ...
- 彻底卸载Xubuntu Kubuntu
卸载Xubuntu -linux-gnu blueman brltty brltty-x11 catfish cheese-common dbus-user-session dconf-cli deb ...
- C# 循环时,操作另外一个进程直到操作完成,循环继续执行
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Angular.js指令
ng-style <input type="button" value="set color" ng-click="myStyle={col ...
- 《linux 必读》
1. linux 内核设计与实现 2. 深入理解 linux 内核
- python反反爬,爬取猫眼评分
python反反爬,爬取猫眼评分.解决网站爬取时,内容类似:$#x12E0;样式,且每次字体文件变化.下载FontCreator . 用FontCreator打开base.woff.查看对应字体关系 ...
- PostgreSql之在group by查询下拼接列字符串
首先创建group_concat聚集函数: CREATE AGGREGATE group_concat(anyelement) ( sfunc = array_append, -- 每行的操作函数,将 ...
- 20190411RAID磁盘阵列及CentOS7系统启动流程
RAID磁盘阵列及CentOS7系统启动流程(week2_day3) RAID概念 磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构 ...
- 基于ROS的运动识别
#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy import cv2 import numpy as np from sensor ...
- 14: InfluxDB+Grafana打造大数据监控利器
参考博客: https://www.cnblogs.com/davidwang456/p/7795263.html