//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)的更多相关文章

  1. Socket 阻塞模式和非阻塞模式

    阻塞I/O模型: 简介:进程会一直阻塞,直到数据拷贝 完成 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返 ...

  2. 看到关于socket非阻塞模式设置方式记录一下。

    关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的:我打个很简单的比方,如果你调用socket send函数时: 如果是阻塞模式下: send先比较待发送数据的长度len和套接 ...

  3. 服务器编程心得(四)—— 如何将socket设置为非阻塞模式

    1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ ...

  4. PHP非阻塞模式 (转自 尘缘)

    让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_re ...

  5. TCP同步与异步及阻塞模式,多线程+阻塞模式,非阻塞模式简单介绍

    首先我简单介绍一下同步TCP编程 与异步TCP编程. 在服务端我们通常用一个TcpListener来监听一个IP和端口.客户端来一个请求的连接,在服务端可以用同步的方式来接收,也可以用异步的方式去接收 ...

  6. UDP socket 设置为的非阻塞模式

    UDP socket 设置为的非阻塞模式 Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct so ...

  7. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  8. 转:PHP非阻塞模式

    你可以任意转摘“PHP非阻塞模式”,但请保留本文出处和版权信息.作者:尘缘,QQ:130775,来源:http://www.4wei.cn/archives/1002336 让PHP不再阻塞当PHP作 ...

  9. 转:PHP中实现非阻塞模式

    原文来自于:http://blog.csdn.net/linvo/article/details/5466046 程序非阻塞模式,这里也可以理解成并发.而并发又暂且可以分为网络请求并发 和本地并发 . ...

随机推荐

  1. KeepAlived+HaProxy+MyCat+Percona双机热备PXC集群

    一.搭建PXC集群 1.环境:centos7+PXC5.7.21+mycat1.6.5 2.卸载mariadb rpm -qa | grep mariadb* yum -y remove mariad ...

  2. Gem install Mysql2的问题

    运行 ‘bundle install’ 或者 ‘gem install mysql2′ 遇到如下错误 > gem install mysql2 ERROR: Error installing m ...

  3. [转载]Oracle日期周详解IW

    1 ORACLE中周相关知识描述 1.1           日期格式化函数 TO_CHAR(X [,FORMAT]):将X按FORMAT格式转换成字符串.X是一个日期,FORMAT是一个规定了X采用 ...

  4. Linux基础篇

    Linux入门 2.1 Linux介绍 1)Linux是一款操作系统,特点:免费.开源.安全.高效.稳定.处理高并发非常强悍,半年至一年重启一次机即可,比Windows强悍,现在很多企业级项目都部署到 ...

  5. js的常见的三种密码加密方式-MD5加密、Base64加密和解密和sha1加密详解总结

    写前端的时候,很多的时候是避免不了注册这一关的,但是一般的注册是没有任何的难度的,无非就是一些简单的获取用户输入的数据,然后进行简单的校验以后调用接口,将数据发送到后端,完成一个简单的注册的流程,那么 ...

  6. Windows 安装配置MongoDB

    1.安装 下载安装包 直接下一步. 2.添加环境变量 3.bin同级目录下新建data文件夹,data文件夹下新建db和log文件夹 4.输入命令启动mongodb服务 mongod --dbpath ...

  7. eclipse如何忽略、过滤不需要提交到svn的文件和目录

    1.进入navigator视图 2.选中不需要提交到svn的目录或者文件,右键team->添加至svn:ignore 3.如图:

  8. Spark机器学习基础三

    监督学习 0.线性回归(加L1.L2正则化) from __future__ import print_function from pyspark.ml.regression import Linea ...

  9. 举例理解JDK动态代理

    JDK动态代理 说到java自带的动态代理api,肯定离不开反射.JDK的Proxy类实现动态代理最核心的方法: public static Object newProxyInstance(Class ...

  10. transform:rotate3d/tranlate3d

    transform:rotate3d(x,y,z,angle); rotate3d 代表 在3D空间,元素沿着 经过原点(0,0,0) 和 三维坐标(x,y,z) 2点的直线进行旋转.其中: x:是一 ...