windows—socket函数整理
- 格式:docx
- 大小:18.05 KB
- 文档页数:4
socket 知识点总结Socket是计算机网络中的一个概念,用于描述在不同主机之间进行通信的一种方法。
本文将对Socket的基本概念、通信模型、常用函数以及应用场景进行总结。
一、Socket的基本概念Socket是一种通信机制,用于实现不同主机之间的数据传输。
它是对TCP/IP协议的封装,可以通过网络传输数据。
在网络编程中,Socket通常被称为“套接字”,它提供了一种接口,使得不同主机之间可以建立连接、发送和接收数据。
二、Socket的通信模型Socket的通信模型包括服务器-客户端模型和点对点模型。
1. 服务器-客户端模型:在这种模型中,服务器端首先创建一个Socket并绑定到指定的端口,然后监听客户端的连接请求。
当有客户端请求连接时,服务器端接受连接,并创建一个新的Socket与客户端进行通信。
通过这个新的Socket,服务器端可以向客户端发送数据,也可以接收客户端发送的数据。
2. 点对点模型:在这种模型中,两个主机之间可以直接进行通信,无需服务器的参与。
每个主机都可以创建一个Socket,并通过该Socket与对方建立连接,进行数据的发送和接收。
三、Socket的常用函数在网络编程中,我们可以使用一系列的Socket函数来实现不同的功能。
1. socket()函数:用于创建一个Socket。
它接受三个参数,分别是地址域(AF_INET表示IPv4)、类型(SOCK_STREAM表示面向连接的TCP套接字)和协议(通常为0,表示根据地址域和类型自动选择合适的协议)。
2. bind()函数:用于将一个Socket绑定到一个特定的地址和端口。
它接受两个参数,分别是Socket和一个地址结构体,包含了要绑定的IP地址和端口号。
3. listen()函数:用于将一个Socket设置为监听状态,等待客户端的连接请求。
它接受一个参数,表示等待连接的队列的最大长度。
4. accept()函数:用于接受客户端的连接请求,并创建一个新的Socket进行通信。
Socket 函数说明1.1 库函数综述1.1.1 套接字函数表 1.1 Windows Sockets 1.1 版本Berkeley Sockets函数函数名说明accept()确认外来连接,并将它与一个立即建立的数据套接字联系起来。
原始套接字返回到监听状态bind() 给未命名套接字赋一个本地名closesocket()从进程对象参考表中删去一个套接字,只有当SO_LINGER设置时才阻塞connect()在指定套接字上初始化连接getpeername() 获取与指定套接字连接的对等方的名字getsockname() 获取指定套接字的当前名字getsockopt() 获取与指定套接字相关的选项htonl() 将一个32位数从主机字节顺序转换为网络字节顺序htons() 将一个16 位数从主机字节顺序转换为网络字节顺序inet_addr() 将一个用网际标准点分表示法表示的字符串地址转换成网际地址值inet_ntoa() 将一个网际地址值转换成一个用点分十进制表示法表示的字符串地址ioctlsocket() 为套接字提供控制listen() 在指定套接字上监听外来连接ntohl() 将一个32位数从网络字节顺序转换为主机字节顺序ntohs() 将一个16 位数从网络字节顺序转换为主机字节顺序recv()从一个连接的套接字上接收数据recvfrom()从一个连接或未连接的套接字上接收数据select()执行多路同步I/Osend()给一个连接套接字发送数据sendto()给一个连接或未连接套接字发送数据setsockopt() 设置与指定套接字相关的选项shutdown() 关闭全双工连接的一部分socket() 建立一个通讯用的末端点,返回一个套接字注:标红函数作用在阻塞套接字上可以阻塞。
这些函数根据功能的不同可以分为如下几类:(1) 套接字函数。
此类函数包括socket(),bind(),getpeername(),getsockname()和closesocket(),它们主要完成创建,关闭套接字功能,以及对套接字命名与名字获取。
winsocket的基本概念和API函数勿在浅沙筑高楼。
在谈论TServerSocket等组件编写之前,这里先对Winsock中一些基本概念和API函数做一个简单的说明。
一、定址要通过Winsock建立通信,必须了解如何利用指定的协议为工作站定址。
Winsock 2引入了几个新的、与协议无关的函数,它们可和任何一个地址家族一起使用;但是大多数情况下,各协议家族都有自己的地址解析机制,要么通过一个函数,要么作为一个投给getsockopt的选项。
因为目前网络编程中用的最多最普遍的也许就是TCP/IP协议了,所以这里主要介绍此协议下的WinSock编程。
1、IP网际协议(Internet Protocol, IP)是一种用于互联网的网络协议,已经广为人知。
它可广泛用于大多数计算机操作系统上,也可用于大多数局域网LAN(比如办公室小型网络)和广域网WAN(比如说互联网)。
从它的设计看来,IP是一个无连接的协议,不能保证数据投递万无一失。
两个比它高级的协议(TCP和UDP)用于依赖IP协议的数据通信。
2、TCP面向连接的通信是通过“传输控制协议”(Transmission Control Protocol, TCP)来完成的。
TCP提供两台计算机之间的可靠无错的数据传输。
应用程序利用TCP进行通信时,源和目标之间会建立一个虚拟连接。
这个连接一旦建立,两台计算机之间就可以把数据当作一个双向字节流进行交换。
3、UDP无连接通信是通过“用户数据报协议”(User Datagram Protocol, UDP)来完成的。
UDP不保障可靠数据的传输,但能够向若干个目标发送数据,接收发自若干个源的数据。
简单地说,如果一个客户机向服务器发送数据,这一数据会立即发出,不管服务器是否已准备接收数据。
如果服务器收到了客户机的数据,它不会确认收到与否。
数据传输方法采用的是数据报。
TCP和UDP两者都利用IP来进行数据传输,一般称为TCP/IP和UDP/IP。
windowssocket函数详解windows socket函数详解 近期⼀直⽤第三⽅库写⽹络编程,反倒是遗忘了⽹络编程最底层的知识。
因⽽产⽣了整理Winsock函数库的想法。
以下知识点均来源于MSDN,本⼈只做翻译⼯作。
虽然很多前辈都做已了此类⼯作,但亲⼒亲为总记得清楚点。
0:函数库头⽂件1 #include <WinSock2.h>2#pragma comment(lib,"Ws2_32.lib ")1:WSAStartup 初始化Ws2_32.dll的函数description:The WSAStartup function initiates use of the Winsock DLL by a process. WSAStartup 函数⽤于初始化供进程调⽤的Winsock相关的dll。
1int WSAStartup(2 __in WORD wVersionRequested,3 __out LPWSADATA lpWSAData4 );Parameters wVersionRequestedThe highest version of Windows Sockets specification that the caller can use. The high-order byte specifies the minor version number; the low-order byte specifies the major version number.The current version of the Windows Sockets specification is version 2.2. The current Winsock DLL, Ws2_32.dll, supports applications that request any of the following versions of Windows Sockets specification,1.0、1.1、2.0、2.1、2.2。
socket函数详解1.socket函数⽤于创建⼀个新的socket,也就是向系统申请⼀个socket资源。
socket函数⽤户客户端和服务端。
//函数声明int socket(int domain, int type, int protocol);参数说明: domain:协议域,⼜称协议族(family)。
常⽤的协议族有AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域Socket)、AF_ROUTE等。
协议族决定了socket的地址类型,在通信中必须采⽤对应的地址,如AF_INET决定了要⽤ipv4地址(32位的)与端⼝号(16位的)的组合、AF_UNIX决定了要⽤⼀个绝对路径名作为地址。
type:指定socket类型。
常⽤的socket类型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。
流式socket(SOCK_STREAM)是⼀种⾯向连接的socket,针对于⾯向连接的TCP服务应⽤。
数据报式socket(SOCK_DGRAM)是⼀种⽆连接的socket,对应于⽆连接的UDP服务应⽤。
protocol:指定协议。
常⽤协议有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
最后总结,第⼀个参数固定填AF_INET,第⼆个参数固定填SOCK_STREAM,第三个参数固定填0。
除⾮系统资料耗尽,socket函数⼀般不会返回失败。
返回值:成功则返回⼀个socket,失败返回-1,错误原因存于errno 中。
2.⼀个程序最多能打开1024个socket,当然该值由系统参数决定(因为linux⼀切皆⽂件,⽽⼀个程序能打开的最多⽂件数为1024,该值可以修改)。
常⽤socket函数详解常⽤socket函数详解关于socket函数,每个的意义和基本功能都知道,但每次使⽤都会去百度,参数到底是什么,返回值代表什么意义,就是说⽤的少,也记得不够精确。
每次都查半天,经常烦恼于此。
索性都弄得清楚、通透,并记录下来,⼀来便于⾃⼰记忆,再者以防⽇后查阅、回顾。
主要介绍:socket、bind、listen、connect、accept、send、sendto、recv、recvfrom、close、shutdown⽹络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,⽽Unix/Linux基本哲学之⼀就是“⼀切皆⽂件”,都可以⽤“打开open –> 读写write/read –> 关闭close”模式来操作。
我的理解就是Socket就是该模式的⼀个实现,socket即是⼀种特殊的⽂件。
其在linux和windows环境下的头⽂件主要是:#include<sys/socket.h>和#include<WinSock2.h>下⾯较为详细的介绍各个函数的使⽤⽅法,及返回值判断和处理。
另外,若想对函数调⽤后内核的详细动作过程,可参考UNIX⽹络编程第⼀卷或TCPIP详解第⼆卷。
1.socketint socket(int domain,int type, int protocol)_________________________返回值:⾮负描述符 – 成功,-1 - 出错其中:family指明了协议族/域,通常AF_INET、AF_INET6、AF_LOCAL等;type是套接⼝类型,主要SOCK_STREAM、SOCK_DGRAM、SOCK_RAW;protocol⼀般取为0。
成功时,返回⼀个⼩的⾮负整数值,与⽂件描述符类似。
对于windows环境下,在调⽤该函数之前需⾸先调⽤WSAStartup函数完成对Winsock服务的初始化,如#include<WinSock2.h>WSADATA wdata;if ( WSAStartup(MAKEWORD(2,2), &wdata) !=0 ){return INVALID_SOCKET;}后⾯即可调⽤socket函数,参数意义与linux环境⼀致。
Windows Socket学习笔记Socket(套接字)◆先看定义:typedef unsigned int u_int;typedef u_int SOCKET;◆Socket相当于进行网络通信两端的插座,只要对方的Socket和自己的Socket有通信联接,双方就可以发送和接收数据了。
其定义类似于文件句柄的定义。
◆Socket有五种不同的类型:1、流式套接字(stream socket)定义:#define SOCK_STREAM 1流式套接字提供了双向、有序的、无重复的以及无记录边界的数据流服务,适合处理大量数据。
它是面向联结的,必须建立数据传输链路,同时还必须对传输的数据进行验证,确保数据的准确性。
因此,系统开销较大。
2、数据报套接字(datagram socket)定义:#define SOCK_DGRAM 2数据报套接字也支持双向的数据流,但不保证传输数据的准确性,但保留了记录边界。
由于数据报套接字是无联接的,例如广播时的联接,所以并不保证接收端是否正在侦听。
数据报套接字传输效率比较高。
3、原始套接字(raw-protocol interface)定义:#define SOCK_RAW 3原始套接字保存了数据包中的完整IP头,前面两种套接字只能收到用户数据。
因此可以通过原始套接字对数据进行分析。
其它两种套接字不常用,这里就不介绍了。
◆Socket开发所必须需要的文件(以WinSock V2.0为例):头文件:Winsock2.h库文件:WS2_32.LIB动态库:W32_32.DLL一些重要的定义1、数据类型的基本定义:这个大家一看就懂。
typedef unsigned char u_char;typedef unsigned short u_short;typedef unsigned int u_int;typedef unsigned long u_long;2、网络地址的数据结构,有一个老的和一个新的的,请大家留意,如果想知道为什么,请发邮件给Bill Gate。
(⼗⼀)socket、connect、bind函数详解⼀、socket函数1、头⽂件:#include <sys/types.h> /* See NOTES */#include <sys/socket.h>2、函数原型:int socket(int domain, int type, int protocol);socket函数类似于open,⽤来打开⼀个⽹络连接,如果成功则返回⼀个⽹络⽂件描述符(int类型),之后我们操作这个⽹络连接都通过这个⽹络⽂件描述符。
dimain:域,⽹络域,⽹络地址范围(IPV4或IPV6等),也就是协议簇type:指定套接字类型:SOCK_STREAM(TCP⽹络)、SOCK_DGRAM(UDP)、SOCK_SEQPACKETprotocol:指定协议,如果指定0,表⽰使⽤默认的协议3、函数形参:3.1、domain:(域)AF_INET ipAF_INET6 ipv6AF_PACKET packet 低级数据包接⼝PF_PACKET 不懂,待了解PF_INET 待了解(AF开头的表⽰地址族,PF开头的表⽰协议族,协议族包含多个地址族,但是当前这种还从未实现,⽽在<sys/socket.h>中PF的值总是与AF的值相等的)3.2、type:(套接字类型):SOCK_RAW 原始套接字 ——>使⽤原始套接字时候调⽤,原始套接字也就是链路层协议SOCK_STREAM 字节流套接字 ——>提供顺序,可靠,双向,基于连接的字节流。
可以⽀持带外数据传输机制。
例如:TCP协议、FTP协议SOCK_DGRAM 数据报套接字 ——>⽀持数据报(⽆连接,不可靠的固定最⼤长度的消息)例如:UDP协议SOCK_SEQPACKET 有序分组套接字 ——>为固定最⼤长度的数据报提供有序,可靠,双向连接的数据传输路径; 消费者需要利⽤每个输⼊系统调⽤读取整个分组3.3、protocol(协议):IPPROTO_IP IP传输协议IPPROTO_TCP TCP传输协议IPPROTO_UDP UDP协议IPPROTO_SCTP SCTP传输协议IPPROTO_ICMP ICMP协议IPPROTO_IGMP IGMP协议⼀般情况下IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP协议⽤的最多,UDP协议protocol就取IPPROTO_UDP,TCP协议protocol就取IPPROTO_TCP;⼀般情况下,我们让protocol等于0就可以,系统会给它默认的协议。
Select模型
Select模型是Windows sockets中最常见的IO模型。
它利用select函数实现IO 管理。
通过对select函数的调用,应用程序可以判断套接字是否存在数据、能否向该套接字写入数据。
如:在调用recv函数之前,先调用select函数,如果系统没有可读数据那么select函数就会阻塞在这里。
当系统存在可读或可写数据时,select函数返回,就可以调用recv函数接收数据了。
可以看出使用select模型,需要两次调用函数。
第一次调用select函数第二次socket API。
使用该模式的好处是:可以等待多个套接字。
select函数中需要三个fd_set结构:
一:准备接收数据的套接字集合,即可读性集合。
二:准备发送数据的套接字集合,即可写性集合。
在select函数返回时,会在fd_set结构中,填入相应的套接字。
readfds数组将包括满足以下条件的套接字:
1:有数据可读。
此时在此套接字上调用recv,立即收到对方的数据。
2:连接已经关闭、重设或终止。
3:正在请求建立连接的套接字。
此时调用accept函数会成功。
writefds数组包含满足下列条件的套接字:
1:有数据可以发出。
此时在此套接字上调用send,可以向对方发送数据。
2:调用connect函数,并连接成功的套接字。
exceptfds数组将包括满足下列条件的套接字:
1:调用connection函数,但连接失败的套接字。
2:有带外(out of band)数据可读。
select函数的使用:
在调用select函数对套接字进行监视之前,必须将要监视的套接字分配给上述三个数组中的一个。
然后调用select函数,再次判断需要监视的套接字是否还在原来的集合中。
就可以知道该集合是否正在发生IO操作。
例如:应用程序想要判断某个套接字是否存在可读的数据,需要进行如下步骤:1:将该套接字加入到readfds集合。
2:以readfds作为第二个参数调用select函数。
3:当select函数返回时,应用程序判断该套接字是否仍然存在于readfds集合。
4:如果该套接字存在与readfds集合,则表明该套接字可读。
此时就可以调用recv 函数接收数据。
否则,该套接字不可读。
在调用select函数时,readfds、writefds和exceptfds三个参数至少有一个为非空。
并且在该非空的参数中,必须至少包含一个套接字。
否则select函数将没有任何套接字可以等待。
timeval结构体用于定义select的等待时间。
structure timeval
{
long tv_sec;//秒。
long tv_usec;//毫秒。
};
当timeval为空指针时,select会一直等待,直到有符合条件的套接字时才返回。
当tv_sec和tv_usec之和为0时,无论是否有符合条件的套接字,select都会立即返回。
当tv_sec和tv_usec之和为非0时,如果在等待的时间内有套接字满足条件,则该函数将返回符合条件的套接字。
如果在等待的时间内没有套接字满足设置的条件,则select会在时间用完时返回,并且返回值为0。
为了方便使用,windows sockets提供了下列宏,用来对fd_set进行一系列操作。
使用以下宏可以使编程工作简化。
FD_CLR(s,*set);从set集合中删除s套接字。
FD_ISSET(s,*set);检查s是否为set集合的成员。
FD_SET(s,*set);将套接字加入到set集合中。
FD_ZERO(*set);将set集合初始化为空集合。
在开发Windows sockets应用程序时,通过下面的步骤,可以完成对套接字的可读写判断:
1:使用FD_ZERO初始化套接字集合。
如FD_ZERO(&readfds);
2:使用FD_SET将某套接字放到readfds内。
如:
FD_SET(s,&readfds);
3:以readfds为第二个参数调用select函数。
select在返回时会返回所有fd_set集合中套接字的总个数,并对每个集合进行相应的更新。
将满足条件的套接字放在相应的集合中。
4:使用FD_ISSET判断s是否还在某个集合中。
如:
FD_ISSET(s,&readfds);
5:调用相应的Windows socket api 对某套接字进行操作。
select返回后会修改每个fd_set结构。
删除不存在的或没有完成IO操作的套接字。
这也正是在第四步中可以使用FD_ISSET来判断一个套接字是否仍在集合中的原因。
看例子,该例演示了一个服务器程序使用select模型管理套接字。
[cpp]
SOCKET listenSocket;
[cpp]
SOCKET acceptSocket;
FD_SET socketSet;
FD_SET writeSet;
FD_SET readSet;
FD_ZERO(&socketSet);
FD_SET(listenSocket,&socketSet);
while(true)
{
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
readSet=socketSet;
writeSet=socketSet;
//同时检查套接字的可读可写性。
int ret=select(0,&readSet,&writeSet,NULL,NULL);
if(ret==SOCKET_ERROR)
{
return false;
}
sockaddr_in addr;
int len=sizeof(addr);
//是否存在客户端的连接请求。
if(FD_ISSET(listenSocket,&readSet))//在readset中会返回已经调用过listen的套接字。
{
acceptSocket=accept(listenSocket,(sockaddr*)&addr,&len);
if(acceptSocket==INVALID_SOCKET)
{
return false;
}
else
{
FD_SET(acceptSocket,&socketSet);
}
}
for(int i=0;i<socketSet.fd_count;i++)
{
if(FD_ISSET(socketSet.fd_array[i],&readSet))
{
//调用recv,接收数据。
}
if(FD_ISSET(socketSet.fd_array[i]),&writeSet)
{
//调用send,发送数据。
}
}
}。