Win32平台上的Winsock编程,Winsock是一个与协议无关的接口。以下协议是我们需要了解的:

网络协议的特征包括:

  1、  面向消息

  2、  面向连接和无线接

  3、  可靠性和次序性

  4、  从容关闭(这是指协议中断,连接不会立即中断)

  5、  广播数据

  6、  多播数据

  7、  服务质量(QOS)

  8、  部分消息(大数据进行分段发送,分段接受)

  9、  路由选择(考虑协议是否可路由)

  10、  字节序

  11、  最大传输单元

Windows支持的协议如下图

Winsocket协议相关结构介绍

//获得系统中安装的网络协议的相关信息
int WSAEnumProtocols(
_In_ LPINT lpiProtocols,//
_Out_ LPWSAPROTOCOL_INFO lpProtocolBuffer,//
_Inout_ LPDWORD lpdwBufferLength//
);

其中的相关信息都保存在参数二当中,这个一个数据结构

 //本机协议信息
typedef struct _WSAPROTOCOL_INFO {
DWORD dwServiceFlags1;//协议标志
DWORD dwServiceFlags2;//
DWORD dwServiceFlags3;//
DWORD dwServiceFlags4;//
DWORD dwProviderFlags;//
GUID ProviderId;//
DWORD dwCatalogEntryId;//
WSAPROTOCOLCHAIN ProtocolChain;//
int iVersion;//
int iAddressFamily;//
int iMaxSockAddr;//
int iMinSockAddr;//
int iSocketType;//
int iProtocol;//
int iProtocolMaxOffset;//
int iNetworkByteOrder;//
int iSecurityScheme;//
DWORD dwMessageSize;//
DWORD dwProviderReserved;//
TCHAR szProtocol[WSAPROTOCOL_LEN+];//
} WSAPROTOCOL_INFO, *LPWSAPROTOCOL_INFO;//

而其中比较重要的参数是dwServiceFlags1,如下图

如何打开Socket

  在可以调用一个Winsock函数之前,必须先加载一个版本正确的Winsock库。Winsock启动例程是WSAStartip();

第一个参数是准备加载的Winsock库的版本号。就目前的 Win32平台而言,Winsock2库的最新版本是 2.2。唯一的例外是 Windows CE,它只支持 Winsock1.1版。如果需要Winsock2.2版,指定这个值(0x0202)或使用宏MAKEWORD(2,2)即可。高位字节指定副版本,而低位字节则指定主版本。

  第二个参数是 WSADATA结构,它是调用完成之后立即返回的。

  接着使用Winsocket函数

  最后清除,记住,每次调用WSACleanup,都需要调用相应的 WSACleanup,因为每次启动调用都会增加对加载 Winsock DLL的引用次数,它要求调用同样多次的 WSACleanup,以此抵消引用次数。

 // WSAData数据结构
typedef struct WSAData {
WORD wVersion;//Winsock版本号
WORD wHighVersion;//最高版本号
char szDescription[WSADESCRIPTION_LEN+];//Winsock说明
char szSystemStatus[WSASYS_STATUS_LEN+];//系统状态信息
unsigned short iMaxSockets;//套接字的最大编号
unsigned short iMaxUdpDg;//UDP数据报的最大容量
char FAR *lpVendorInfo;//厂商专有信息
} WSADATA, *LPWSADATA;
//1.启用socket库,初始化
WSAData wsa;
if ( != WSAStartup(MAKEWORD(,),&wsa))
{
cout<<"Socket2.0初始化失败,Exit!"<<endl;
return ;
}
//2.创建套接字
......
//3.绑定套接字
.....
//4.监听
......
//5.连接
.....
//6.通信
....
//7.断开
....
//8.清除
if (!WSACleanup())
{
WSAGetLastError();
return;
}

SOCKET 的使用有两种定义方式

//方法1
SOCKET WSASocket(
_In_ int af,
_In_ int type,
_In_ int protocol,
_In_ LPWSAPROTOCOL_INFO lpProtocolInfo,//0表示默认的协议条目
_In_ GROUP g,//组参数始终为0
_In_ DWORD dwFlags //
);
//方法2
SOCKET WSAAPI socket(
_In_ int af,//地址家族
_In_ int type,//套接字类型
_In_ int protocol//协议字段
);

类型参考如

  在类型里可以看到一个不常用的套接字,原始套接字。

原始套接字

  raw socket,即原始套接字,可以接收本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的。

  原始套接字一种通信,允许你把其他协议封装在 U D P数据包中,比如说“互联网控制消息协议”(I C M P)。I C M P的目的是投递互联网主机间的控制、错误和信息型消息。由于 I C M P不提供任何数据传输功能,因此不能把它与 U D P或T C P同等看待,但它和 I P本身属于同一个级别。

创建套接字常用的结构如下

struct sockaddr {
ushort sa_family;//地址家族啊
char sa_data[];//不同网络地址结构的大小
}; struct sockaddr_in{
short sin_family;//地址家族
unsigned short sin_port;//IP端口
struct in_addr sin_addr;//IP地址
char sin_zero[];//填充结构,使其余SOCKETADDR的大小一致
};

还有一点需要注意在网络中传输的数据的顺序是网络字节顺序,和主机字节顺序不同,以下是几个相互转换的函数:

//将一个ip地址转换成一个32位无符号长整数。
unsigned long inet_addr(
_In_ const char *cp
);
//将主机字节顺序转换成网络字节顺序
u_long WSAAPI htonl(
_In_ u_long hostlong
);
//将主机字节顺序转换成16位网络字节顺序返回
u_short WSAAPI htons(
_In_ u_short hostshort
);
一下两个刚好相反:
//将16位网络字节顺序转换成主机字节顺序返回
u_short WSAAPI ntohs(
_In_ u_short netshort
);
//将网络字节顺序转换成主机字节顺序
u_long WSAAPI ntohl(
_In_ u_long netlong
);

名字解析

  通过已知信息获取网络信息

//通过主机名获得主机的相关信息,返回值为hostent结构指针
struct hostent* FAR gethostbyname(
_In_ const char *name
); //通过主机名获得主机ip地址的相关信息,返回值为hostent结构指针
struct hostent* FAR gethostbyaddr(
_In_ const char *addr,
_In_ int len,
_In_ int type
); //hostent结构
typedef struct hostent {
char FAR *h_name;//正式主机名
char FAR FAR **h_aliases;//主机的别名
short h_addrtype;//ip地址类型
short h_length;//IP地址长度
char FAR FAR **h_addr_list;//主机的IP地址(网络字节顺序)
} HOSTENT, *PHOSTENT, FAR *LPHOSTENT; //获得已知服务的端口号
struct servent* FAR getservbyname(
_In_ const char *name,//服务名
_In_ const char *proto//随便指向一个字串,这个字串表明name中的服务是在这个参数中的协议下面注册的。
);

  

Windows网络编程笔记4 -- Winsock 协议相关知识的更多相关文章

  1. Windows网络编程笔记6 --- WinSock I/O 控制方法

    Windows提供了两种方式“套接字模式”和“套接字I/O模型”,可对一个套接字上的I/O行为加以控制.套接字模式用于决定在随一个套接字调用时,那些 Winsock函数的行为.其中的模型包括括sele ...

  2. Windows网络编程笔记5 -- 其他套接字

    包括红外线套接字(IrSock).IPX/SPX 套接字.NetBIOS 套接字.AppleTalk 套接字.ATM 套接字等.对这些套接字进行简单介绍. 第一.红外线套接字(I r S o c k) ...

  3. Windows网络编程笔记1

    第一部分 传统网络API 传统的网络接口NetBIOS.重定向器.邮槽.命名管道等.第一,NetBIOS(Network Basic Input/Output System, NetBIOS)“网络基 ...

  4. Windows网络编程笔记3 ---- 邮槽和命名管道

    邮槽和命名管道的使用方法也很简单,只需几个有限的函数就可以实现双方的通信. 第三.邮槽 邮槽----进程间通信机制. 通过邮槽客户进程可以将消息通过广播给一个或多个服务进程.这是一个单向通信机制,缺点 ...

  5. Windows网络编程笔记2

    这一次看看重定向器和如何使用Netbios函数获取本机mac地址 5.获取Mac地址 利用NCBASTAT命令实现,适配器状态命令会返回一个 ADAPTER_STATUS结构,紧接着是大量 NAME_ ...

  6. Winsock网络编程笔记(1)----入门

    今天第一次接触winsock网络编程,看的资料是Windows网络编程第二版.通过博客记住自己的看书笔记.. 在这里贴出第一个程序,虽然程序什么都没做,但以此作为入门,熟悉其网络编程风格.. #inc ...

  7. Linux网络编程笔记(修订版)

    我的网络编程笔记, 因为最近又要做Linux下的网络编程,故重新修订, 其中一些内容参考了文末的链接及文章 1.   基本概念 2.   基本接口 2.1.   打开一个socket 2.2.   将 ...

  8. Windows网络编程 2 【转】

    Windows网络编程使用winsock.Winsock是一个基于Socket模型的API,在Windows系统中广泛使用.使用Winsock进行网络编程需要包含头文件Winsock2.h,需要使用库 ...

  9. storysnail的Windows串口编程笔记

    storysnail的Windows串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据 ...

随机推荐

  1. Spring Boot 的配置文件application.properties

    Spring Boot 中的application.properties 是一个全局的配置文件,放在src/main/resources 目录下或者类路径的/config下. 作为全局配置文件的app ...

  2. LeetCode Valid Palindrome 有效回文(字符串)

    class Solution { public: bool isPalindrome(string s) { if(s=="") return true; ) return tru ...

  3. happy2018暑期集训课后习题001

    根据需求补全下面的代码: 需求: 每行输入三个整数a.b.c,根据a的值不同对b和c进行不同的操作: a为0时,计算b+c a为1时,计算b-c a为2时,计算b*c a为3时,计算b/c 并输出操作 ...

  4. 小记:vue 及 react 的工程项目入口小结及 webpack 配置多页面应用参考

    一.前言 闲暇时间,看了下前端的基础知识,有幸参与了公司公众号项目前面的一个阶段,学习到了一些前端框架的相关知识 小结了一下 自己练习通过新建一个个文件组织起项目的过程中的一些理解 二.项目入口 vu ...

  5. java之打印机服务通俗做法

    javax.print包是API的主包,其中包含的类和接口能够让你:1)发现打印服务(Print Services)2)指定打印数据的格式 3)从一个打印服务创建打印工作(print jobs) 4) ...

  6. JAVA入门2019-JAVA配置(windows7和10通用)IDE推荐和相关软件

    如何安装JDK 首先,略过"什么是JDK",非要问,这就是编译环境,JRE是运行环境.一个写程序,一个部署运行. 下载的方法:百度 java se 或者openJDK(两个差不多, ...

  7. libav(ffmpeg)简明教程(1)

    突然发现又有好久没有写技术blog了,主要原因是最近时间都用来研究libav去了(因为api极类似ffmpeg,虽然出自同一份代码的另外一个分支,因项目选用libav,故下文均用libav代替),其实 ...

  8. IOS CALayer基本使用 (图层)

    ● 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层(CALayer) ● 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView 的l ...

  9. AngularJs学习笔记-数据绑定、管道

    数据绑定.管道 (1)数据绑定(Angular中默认是单向绑定) 1.[]方括号 可以用于子组件传值 由于是单向绑定,所以当子组件中的iStars属性发生改变时,不会影响到父组件中product.ra ...

  10. Oracle小技巧_不同表空间不同用户导入导出数据dmp

    [博主注:数据库方面 ITPUB网站及博客内容非常丰富]   转载来源ITPUB 博客 经常有人会问:原来的数据在USERS表空间里面,我想把它IMP进APP表空间,我已经修改了目的用户的默认表空间, ...