linux下socket调用的函数介绍

对于socket,各个平台都给出了比较简单的调用接口,应用起来相当的方便,但是在应用过程中仍然会遇到这样那样的问题;现在对于socket的基本应用做一下大致介绍
1.TCP/UDP socket介绍
由于基于ip的socket相对使用较少,所以此次就不对此进行介绍;TCP和UDP都是端到端的传输层的相关协议,但是它们也有各自的特点:TCP为面向连接的、可靠的、基于字节流的传输协议,而UDP则是无连接的、非可靠的、基于报文的传输协议;它们各自不同的特点也决定了它们不同的服务对象,而对于重要性而言,则是同等重要。

2.TCP/UDP socket实现
(1).初始化socket
对于socket的初始化可以分为UDP、TCP SERVER及TCP CLIENT这几种,每种调用的函数都有所区别,下面对于大致介绍下涉及的函数

创建socket
function : int socket(int domain, int type, int protocol);
domain: 应用程序使用的通信协议的协议族;主要有AF(Address Family) 和PF(Protocol Family)两种,理论上建立socket时是指定协议,应该用PF_xxxx,设置地址时应 该用AF_xxxx
type: 创建的套接字类型,流套接字类型为SOCK_STREAM(适用于TCP)、数据报套接字类型为SOCK_DGRAM(适用于UDP)
protocol: 应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议
返回值为创建的socket的标示ID

配置socket
function :int setsockopt(SOCKET s,int level,int optname, const char FAR *optval,int optlen);
s:标识一个套接口的描述字,其值为创建socket时的返回值
level:选项定义的层次;一般使用SQL_SOCKET
SOL_SOCKET: 基本套接口;
IPPROTO_IP: IPv4套接口
IPPROTO_IPV6: IPv6套接口
IPPROTO_TCP: TCP套接口
optname:需设置的选项,此处根据level的不同可以有不同的选项选择,下面举例设置为SQL_SOCKET时几个代表选项的说明
SO_REUSERADDR: 允许重用本地地址和端口,充许绑定已被使用的地址(或端口号),可以参考bind的man
SO_BROADCAST: 允许发送广播数据
SO_RCVBUF 接收缓冲区大小,设置接收缓冲区的保留大小
SO_SNDBUF 发送缓冲区大小,设置发送缓冲区的保留大小
optval:指针,指向存放选项值的缓冲区;在optname=SO_REUSERADDR下:其指向的内容为true,调用closesocket()一般不会立即关闭socket,而经历 TIME_WAIT的过程;其指向的内容为false,则立刻关闭socket
optlen:optval缓冲区长度
返回值为设置状态
此函数可以在一次初始化中调用多次

绑定socket
function : int bind(SOCKET s, struct sockaddr *sock_addr, int sock_addr_len)
s: 标识一个套接口的描述字,其值为创建socket时的返回值
sock_addr: 需要绑定的套接字的信息,主要包括三部分(协议族,ip地址,端口号),类似
sock_addr->sin_family = AF_INET; //此协议族的说明与创建socket时一致
sock_addr->sin_addr.s_addr = htonl(INADDR_ANY); //此处绑定的本机,也可以使用inet_addr(send_addr)得到某个显示的ip地址
sock_addr->sin_port = htons(recv_port); //绑定端口号,需要将其转化为网络字节序
sock_addr_len:绑定的套接字的信息的长度,即可以普遍设为sizeof(struct sockaddr) 
返回值为绑定成功与否的状态

连接TCP服务端
function : int connect(SOCKET S,struct sockaddr *serv_addr,int serv_addr_len)
s: 标识一个套接口的描述字,其值为创建socket时的返回值
serv_addr: 需要绑定的套接字的信息,主要包括三部分(协议族,ip地址,端口号)
serv_addr_len:绑定的套接字的信息的长度,即可以普遍设为sizeof(struct sockaddr) 
返回值为连接成功与否的状态

可连接最大TCP客户端数
function : int listen(int num)
num : 可连接的最大的TCP客户端的数量
返回值为设置成功与否的状态

从上面的函数介绍中可以发现,有得函数只是针对于特定的某个socket,而有得则是针对所有的,下面是创建三种主要的socket时的主要函数调用顺序
创建UDP: 1.socket() —— 创建一个socket; 2.setsockopt()—— 配置socket,可以有多个; 3. bind() —— 将创建的socket绑定到具体的套接字上
创建TCP SERVER: 1.socket() —— 创建一个socket; 2.setsockopt()—— 配置socket,可以有多个; 3. bind() —— 将创建的socket绑定到具体的套接字上; 4. listen() —— 设置最大监听数
创建TCP CLIENT: 1.socket() —— 创建一个socket; 2.setsockopt()—— 配置socket,可以有多个; 3. connect() —— 连接到一个TCP服务端

(2).数据发送
TCP数据发送
function : int send( SOCKET s, const char FAR* buf, int len, int flags);
s:标识一个套接口的描述字。如果为TCP SERVER,则此值为连接的客户端的socket标示;如果为TCP CLIENT,则此值为本身创建的socket值
buf:包含待发送数据的缓冲区。
len:buf缓冲区中数据的长度。
flags:调用方式标志位。默认为0时表示没有特殊行为
  MSG_OOB: 表示数据应该带外发送,所谓带外数据就是TCP紧急数据。
   MSG_PEEK: 表示使有用的数据复制到缓冲区内,但并不从系统缓冲区内删除。(一般为取出后删掉)
   MSG_DONTROUTE: 表示不要将包路由出去。
返回值为发送的数据量或者错误信息(此处没有指定发送目的地主要是因为tcp在accept或者connect的时候已经建立起连接)

UDP数据发送
function : int sendto(SOCKET s, const char FAR* buf, int len, int flags,const struct sockaddr FAR* to, int tolen);
s:标识一个套接口的描述字,其值为创建socket时的返回值
buf:包含待发送数据的缓冲区。
len:buf缓冲区中数据的长度。
flags:调用方式标志位。默认为0时表示没有特殊行为,也可以为下面的组合
  MSG_OOB: 表示数据应该带外发送,所谓带外数据就是TCP紧急数据。
   MSG_PEEK: 表示使有用的数据复制到缓冲区内,但并不从系统缓冲区内删除。(一般为取出后删掉)
   MSG_DONTROUTE: 表示不要将包路由出去。
to:指针,指向目的套接口的地址。
tolen:to所指地址的长度。
返回值为发送的数据量长度或者错误信息

(3). 数据接收
TCP数据接收
function : int recv( SOCKET s, char FAR* buf, int len, int flags ); 
s:标识一个套接口的描述字。如果为TCP SERVER,则此值为连接的客户端的socket标示;如果为TCP CLIENT,则此值为本身创建的socket值
buf:保存待接收数据的缓冲区
len:最大接收长度
flags:调用方式标志位。默认为0时表示没有特殊行为(有数据就返回,可以不用等到最大数据量到来),也可以是下面的组合
MSG_OOB:表示能够接收和发送带外的数据.而为紧急的数据使用带外数据. 
MSG_PEEK:表示只是从系统缓冲区中读取内容,而不清除系统缓冲区的内容。这样下次读的时候,仍然是相同的内容。一般在有多个进程读写数据时能够使用这个标志。
MSG_WAITALL:表示等到任何的信息到达时才返回。使用这个标志的时候recv会一直阻塞,直到指定的条件满足,或是发生了错误。 1)当读到了指定的字节时,函数正常返回,返回值等于len 2)当读到了文档的结尾时,函数正常返回.返回值小于len 3)当操作发生错误时,返回-1,且配置错误为相应的错误号(errno)
返回值为接收到得数据量长度或者错误信息

UDP数据接收
function : int recvfrom( SOCKET s, char FAR* buf, int len, int flags,const struct sockaddr FAR* send, int *sendlen); 
s:标识一个套接口的描述字。如果为TCP SERVER,则此值为连接的客户端的socket标示;如果为TCP CLIENT,则此值为本身创建的socket值
buf:保存待接收数据的缓冲区
len:最大接收长度
flags:调用方式标志位。默认为0时表示没有特殊行为
send:指针,可以将发送端的套接字的信息存储在此空间中,然后查看发送端的信息
tolen:指针,要存储的发送端套接字的缓存的大小
返回值为接收到得数据量长度或者错误信息

非阻塞接收时监听文件句柄
function : int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
ndfs:select监视的文件数,视进程中打开的socket数目而定,在linux下一般设为你要监视各socket的最大标识符加一,在windows下可以忽略。
readfds:select监视的可读文件句柄集合。
writefds: select监视的可写文件句柄集合。
exceptfds:select监视的异常文件句柄集合。
timeout:本次select()的超时结束时间。
返回值为监听的文件是否有变化
与之相关的几个宏为
FD_ZERO(fd_set *fdset):清空fdset与所有文件句柄的联系。
FD_SET(int fd, fd_set *fdset):建立文件句柄fd(创建socket值)与fdset的联系。
FD_CLR(int fd, fd_set *fdset):清除文件句柄fd(创建socket值)与fdset的联系。
FD_ISSET(int fd, fd_set *fdset):检查fdset联系的文件句柄fd是否有变化(存在数据收发)

3.总结
本文只是对于socket的比较浅显的介绍,主要目的是让大家对于socket及其相关的函数有个大致的把握。对于具体的应用,还需要大家以后在实践中自己掌握然后进行总结。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值