Socket常用函数总结:
一丶Socket与常用函数概述:
Socket简介:
众所周知,基于网络分层结构,我们构建了目前所使用的网络。而基于分层思想,网络体系中每层只需要完成自己的任务,而网络中每个层次之间的协作是由上层调用下层提供的接口(API)来实现的。Socket就是传输层提供给应用层的网络编程接口,它起源于Unix,目前是事实上的工业标准,所以它的重要性就不言而喻了。Socket是开发基于**客户/服务器(C/S)通信模型应用程序的主要主要手段。它的设计继承了Unix/Linux
”万物皆文件“**的设计哲学,在实际编程中,我们可以把它看作是一种特殊的文件。
Socket标识:
标识通信端点(对外):
- IP地址+端口号
操作系统/进程管理套接字(对内):
- 套接字描述符(小整数)
Sockaddr_in
结构:
struct sockaddr_in{
u_char sin_len; //地址长度
u_char sin_family; //地址族(TCP/IP:AF_INET)
u_short sin_port; //端口号
struct in_addr sin_addr; //IP地址
char sin_zero[8]; //未用(置0)
}
Socket常用函数总览:
-
WSAStartup
:初始化socket库。(仅针对WinSock) -
WSACleanup
:清除/终止 socket库的使用。(仅针对WinSock) -
socket
:创建套接字。 -
closesocket
:释放/关闭套接字。 -
bind
:绑定套接字的本地IP地址和端口号。(通常客户端不需要) -
connect
:”连接“远端服务器。(仅用于客户端) -
listen
:置服务器端TCP套接字为监听模式,并设置队列大小。(仅用于服务器端TCP套接字) -
accept
:接受/提取一个连接请求,创建新套接字,通过新的套接字连接客户端,提供服务。(仅用于服务器端TCP套接字) -
recv
:接受数据。(用于TCP套接字或连接模式的客户端UDP套接字) -
recvfrom
:接受数据报。(用于非连接模式的UDP套接字) -
send
:发送数据。(用于TCP套接字或连接模式的客户端UDP套接字) -
sendto
:发送数据报。(用于非连接模式的UDP套接字) -
setsockopt
:设置套接字选项参数。 -
getsockopt
:获取套接字选项参数。
二丶Socket常用函数详解:
WSAStartup
int WSAStartup(WORD wVersionRequested, LPWSADATA IpWSAData);
-
在Windows系统下,使用Socket的应用程序在使用Socket之前必须首先调用
WSAStartup()
函数。 -
所在头文件
Winsock2.h
-
第一个参数指明程序请求使用的WinSock版本,其中高位字节指明副版本,地位字节指明主版本。
- 十六位进制证数,例如:
0x102
表示2.1版
- 十六位进制证数,例如:
-
第二个参数返回实际的
WinSock
的版本信息。- 指向
WSADATA
结构的指针
- 指向
-
返回值为0时表示成功。
-
例子:使用2.1版本的WinSock的程序代码:
WORD request;
WSADATA ws;
request = MAKEWORD(2,1);
int err = WSAStartup(request,&ws);
if(err != 0){
return false;
}
if(LOBYTE(ws.wVersion) != 2||HIBYTE(ws.wVersion) != 1){
WSACleanup();
return false;
}
return true;
WSACleanup
int WSACleanup(void);
- 应用程序在完成对Socket库的使用后,最后要调用
WSACleanup()
函数。 - 解除与Socket库的绑定。
- 释放Socket库所占用的系统资源。
- 慎用,如果在调用该函数之前没有使用
WSAStartup()
函数,会造成不可预见的错误。 - 返回0表示成功。
socket
int socket(int protofamily,int type, int proto)
- 创建套接字。
- 第一个参数(协议组):
PF_INET
(TCP/IP)AF_INET6
AF_LOCAL
- 第二个参数(套接字类型):
SOCK_STREAM
(流套接字 TCP)SOCK_DGRAM
(数据报套接字 UDP)SOCK_RAW
(原始套接字 程序自己处理数据包,直接面向网络层)
- 第三个参数(协议号):
- 默认为0
- 例子:创建一个流套接字:
struct protoent *p;
p = getprotobyname("tcp");//通过协议名得到协议号
SOCKET sd = socket(PF_INET, SOCK_STREAM, p->p_proto);
- Socket的服务类型:
closesocket
int closesocket(int sd);//Windows
int close(int sd);//Linux
- 关闭一个描述符为
sd
的套接字。 - 如果多个进程共享一个套接字,调用该函数会将套接字的引用次数减1,减至0才会关闭。
- 一个进程中多个县城对一个套接字的使用没有计数。
- 如果进程中一个线程调用该函数将一个套接字关闭,该进程中的其他线程也将不能访问该套接字
- 返回值:
0
:成功SOCKET_ERROR
:失败
bind
int bind(int sd, const struct sockaddr* localaddr, socklen_t addrlen);
- 绑定套接字的本地端点地址。
- IP地址+端口号
- 第一个参数(套接字描述符)
- 第二个参数(端点地址):
- 结构为
sockaddr_in
- 结构为
- 客户端一般不必调用
bind
函数。(因为一般就一个网卡) - 服务器端有可能会连接多个网络,同时拥有多个IP地址,此时应使用地址通配符
INADDR_ANY
来匹配所有连接的IP地址。
connect
int connect(int sd, const struct sockaddr *saddr, socklen_t saddrlen);
- 客户程序调用
connect
函数来使用客户端套接字sd
与特定计算机的特定端口saddr
的套接字进行连接。 - 仅用于客户端
- 可用于TCP客户端也可用于UDP客户端
- TCP客户端:建立TCP连接
- UDP客户端:指定服务器端点地址
listen
int listen(int sd, int queuesize);
- 第一个参数,置服务器端的流套接字
sd
处于监听状态- 仅用于服务端调用
- 仅用于面向连接的流套接字
- 第二个参数,设置连接请求队列大小
- 返回值:
- 0:成功
- SOCKET_ERROR:失败
accept
int accept(int sd, struct sockaddr *caddr, int *caddrlen)
- 服务程序调用
accept
函数从处于监听状态的流套接字sd
的客户连接请求队列中取出排在最前面的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道。- 仅用于TCP套接字
- 仅用于服务器
- 利用返回的新的套接字
newsock
与客户通信。 caddr
和caddrlen
分别用于返回客户端套接字的地址和地址长度
recv
int recv(int sd, void *buffer, int len, int flags);
- 用于从TCP连接的另一端接收数据,或者从调用了
connect
函数的UDP客户端套接字接受服务器发来的数据。
recvfrom
int recvform(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
- 用于从UDP服务器端套接字与未调用
connect
函数的UDP客户端套接字接受对端数据。
send
int send(int sd, const void *buf, size_t len, int flags);
- 用于TCP套接字(客户端与服务器),或者调用了
connect
函数的UDP客户端套接字
sendto
int sendto(int sd, const void *buf, size_t len, int flags);
- 用于UDP服务器端套接字,或者未调用
connect
函数的UDP客户端套接字。
setsockopt
- 设置套接字选项参数
getsockopt
- 获取套接字选项参数