windows下的C++ socket服务器(3)
int make_server_socket(int port)
{ WSADATA inet_WsaData;//
WSAStartup(MAKEWORD(2, ), &inet_WsaData);//
if (LOBYTE(inet_WsaData.wVersion) != 2 || HIBYTE(inet_WsaData.wVersion) != 0)//2
{
WSACleanup();
return -1;
}
int tcp_socket = socket(AF_INET, SOCK_STREAM, );//3
SOCKET s;
struct sockaddr_in saddr;//4
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
saddr.sin_addr.s_addr = INADDR_ANY;
if (::bind(tcp_socket, (const struct sockaddr*)&saddr, sizeof(saddr)) == -)//5
{
cerr << "bind error" << endl;
return -;
}
if (::listen(tcp_socket, ) == -)//6
{
cerr << "listen error" << endl;
return -;
}
return tcp_socket;
}
1 WSADATA inet_WsaData;SAStartup(MAKEWORD(1, 1), &inet_WsaData);
在windows下使用socket的相关函数前,必须通过WSAStartup函数完成对Winsock服务的初始化。
int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
该函数的第一个参数指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本;第二个参数可以用来返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
以前大家使用的都是socket1.1版本,但socket2.0版本已经出来了,所以我这里使用的是socket2.0版本(MAKEWORD(2.0))
1.1版和2.0版的区别:
两者的最重要区别是1.1版只支持TCP/IP协议,而2.0版可以支持多协议。2.0版有良好的向后兼容性,任何使用1.1版的源代码,二进制文件,应用程序都可以不加修改地在2.0规范下使用。
MAKEWORD的定义如下
#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8))
2 if (LOBYTE(inet_WsaData.wVersion) != 2 || HIBYTE(inet_WsaData.wVersion) != 0)用于检测当前的Socket是否为2.0
LOBYTE和HIBYTE是两个宏,在vs2013里定义如下
#define LOBYTE(w) ((BYTE)(((DWORD_PTR)(w)) & 0xff))
#define HIBYTE(w) ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))
WSACleanup();用于解除与Socket库的绑定并释放Socket库所占用的系统资源。
3 int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
socket函数用于建立一个socket,函数原型如下
SOCKET socket(int af, int type, int protocol);
第一个参数af指定应用程序使用的通信协议的协议族,af一般置为AF_INET(表示internetwork: UDP, TCP等);
第二个参数type为协议的Socket类型,常用的有3种:SOCK_STREAM、SOCK_DGRAM和SOCK_RAW。
SOCK_STREAM对应于TCP。
SOCK_DGRAM对应于UDP。
SOCK_RAW称为原始Socket,可以读写ICMP、IGMP、IP报文。前两种类型使用得最多。
第三个参数protocol指定所使用的协议。对于SOCK_STREAM、SOCK_DGRAM两种类型的Socket,该参
数为0,对于原始Socket才需要指定具体的协议。
4 struct sockaddr_in saddr;
sockaddr_in是定义了socket发送和接收数据包的地址的结构体,有四个字段,含义如下
第一个参数short sin_family,指定应用程序使用的通信协议的协议族,af一般置为AF_INET(表示internetwork: UDP, TCP, etc.Internetwork Version 4);
第二个参数u_short sin_port,代表程序使用的IP地址端口,由程序员指定;
第三个参数struct in_addr sin_addr中的s_addr,用于设置IP地址;
第四个参数char sin_zero[8],是为了保证sockaddr_in与SOCKADDR类型的长度相等而填充进来的字段。
例如
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);//使用的端口号
saddr.sin_addr.s_addr = INADDR_ANY;//任意地址均可以,这样任意客户端都可以访问到服务器
5 ::bind(tcp_socket, (const struct sockaddr*)&saddr, sizeof(saddr))
这里使用::表示的位于全局作用域下的bind,由于我之前使用了using namespace std;所以如果没有使用::,它会使用std下的bind,出现一系列的错误
bind函数用来将一个socket套接字绑定到一个地址,很多函数会隐式的调用bind函数。
bind的函数原型如下
int bind(SOCKET s,const struct sockaddr FAR * name,int namelen);
第一个参数指定待绑定的Socket描述符;
第二个参数指绑定到的地址结构,即一个sockaddr类型的数据;
第三个参数指对应的是地址的大小;
如果bind错误,返回-1,
例如
if (::bind(tcp_socket, (const struct sockaddr*)&saddr, sizeof(saddr)) == -1)//绑定到tcp_socket,使用saddr的地址结构,该地址的大小为sizeof(saddr),
{
cerr << "bind error" << endl;
return -1;
}
6 ::listen(tcp_socket, 1)
如果作为一个服务器,在调用socket()、bind()之后需要调用listen()来监听这个socket,如果客户端这时调用connect()发出连接请求,服务器端就会接收到这个请求。
listen的函数原型如下
int listen(SOCKET s,int backlog);
第一个参数为要监听的socket描述字;
第二个参数为相应socket可以排队的最大连接个数。()(当客户链接请求大于这数时(即缓冲池满),其它的未进入链接缓冲池的客户端在tcp层上tcp模块会自动重新链接,直到超时(大约57秒后))
如果listen错误,返回-1,
windows下的C++ socket服务器(3)的更多相关文章
- windows下的C++ socket服务器(1)
windows下的一个C++ socket服务器,用到了C++11的相关内容,现在还不是很完善,以后会不断改进的! #include <winsock2.h>//1 以后会用这种方式对特定 ...
- windows下的C++ socket服务器(2)
int main(int ac, char *av[]) { ); ) { exit(); } thread t; ) { int socket_fd = accept(tcp_socket, nul ...
- windows下的C++ socket服务器(4)
void handleAccept(int socket_fd) { ] = { '\0' }; string cmd; string filename; recv(socket_fd, buf, ) ...
- windows下运行的linux服务器批量管理工具(带UI界面)
产生背景: 由于做服务器运维方面的工作,需要一人对近千台LINUX服务器进行统一集中的管理,如同时批量对LINUX服务器执行相关的指令.同时批量对LINUX服务器upload程序包.同时批量对LINU ...
- syslog之三:建立Windows下面的syslog日志服务器
目录: <syslog之一:Linux syslog日志系统详解> <syslog之二:syslog协议及rsyslog服务全解析> <syslog之三:建立Window ...
- Windows下搭建本地SVN服务器【转】
转自:http://www.linuxidc.com/Linux/2015-01/111563.htm 本文介绍Windows下搭建本地SVN服务器的方法,网上资料比较少也比较旧,大都介绍的是旧版本S ...
- Windows下IIS搭建Ftp服务器
第一步:启用Windows IIS Web服务器 1.1 控制面板中找到"程序"并打开 1.2 程序界面找到"启用或关闭Windows功能"并打开 1.3 上面 ...
- Windows下svn客户端和服务器的安装使用
svn,全称subversion, 是目前用的较多的开源的版本管理工具.相信有些经历的程序员应该都听说过它. 通常的svn服务器是搭建在Linux中,不过如果作为个人或者单个小组使用的话,就可以把sv ...
- Windows下搭建HTTP/HTTPS服务器及测试过程
1 安装Apache http://www.apachehaus.com/cgi-bin/download.plx 选择合适的版本下载 本次下载的是 Apache 2.4.x VC14 Apache版 ...
随机推荐
- Android开发——布局性能优化的一些技巧(一)
0. 前言 上一篇我们分析了为什么LinearLayout会比RelativeLayout性能更高,意义在于分析了这两种布局的实现源码,算是对一个小结论的证明过程,但是对布局性能的优化效果,对这两种布 ...
- 【转载】COM 组件设计与应用(七)——编译、注册、调用
原文:http://vckbase.com/index.php/wv/1218.html 一.前言 上两回中,咱们用 ATL 写了第一个 COM 组件程序,这回中,主要介绍编译.册和调用方法.示例程序 ...
- 6 admin(注册设计)源码解析、单例模式
1.单例模式 https://www.cnblogs.com/yuanchenqi/articles/8323452.html 单例模式(Singleton Pattern)是一种常用的软件设计模式, ...
- JAVAWEB servlet验证登录时进行完全的非空判断防止空值登录
如果不进行完全的非空判断,那么对 "" 这种类型的空值就会导致直接登录 所以需要用下面的字符串处理方法对其进行判断 这样就可以防止空值登录了 容易出现的混淆错误: 这里的空值登录容 ...
- jquery 配合 jsp 实现 ajax 要注意的问题
(这一次 jq 无法执行的原因竟然是: 没导入 jq 的 js 文件!!!!!!!!!!!!!!) 今天在写一个 select change 实现来 ajax 时,发现 jq 无法执行,网上查了下,发 ...
- JS ,substr、 substring、charAt方法的区别
JS 截取字符串substr 和 substring方法的区别,需要的朋友可以参考下,根据需要自行选择. substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.subs ...
- Cisco Packet Tracer中通过集线器组网
Cisco Packet Tracer中可以通过集线器将多台电脑完成通信. Cisco Packet Tracer 6.2.0 一.添加三台电脑设备 1.按照下图1.2步骤操作,2步骤执行三次,拖拽P ...
- Altium 中异形焊盘异形封装的创建图文教程
Altium 中异形焊盘异形封装的创建图文教程 一般不规则的焊盘被称为异型焊盘,典型的有金手指.大型的器件焊盘或者板子上需要添加特殊形状的铜箔(可以制作一个特殊封装代替). 如图27所示,此处我们以一 ...
- 通过Task异步加快对数组的运算
一.介绍 Task是.NetFramework3.0出现的,线程是基于线程池,然后提供了丰富的API. 先用AverageAssign方法把一组数据平均分成n组,再通过遍历n组数据,循环开Task多线 ...
- C# 通用树形数据结构
前言 树在图论中是一种重要的图,由于其自身的许多特殊性质,也是一种重要的计算机数据结构,在很多地方都有用.但是这些树大多都是作为其他应用的内部数据结构来使用.我们无法了解这些树的详细信息,而 .Net ...