Socket的由来
我们可以使用用Socket中的相关函数来完成通信, 应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为Socket(套接字)的接口
如图1所示:
Socket的简介
Socket是通信端点的抽象,它被认为是一种特殊的管道,但和管道不同的是,它对于容纳的数据的大小没有限制。
1、socket函数
包含头文件<sys/socket.h>
功能:创建一个套接字用于通信
原型:int socket(int domain, int type, int protocol);
1.1 域
domain参数有如下:
Linux下,网络协议(网络传输中的一项规则,如TCP/IP、HTTP、FTP协议等)被映射成多个域(domain),也就是socket函数中的domain。我们常用的是:AF_INET和AF_UNIX,AF_INET套接字可以用于通过包括因特网在内的TCP/IP网络进行通信的程序。
1.2 类型
type:指定socket通信的特性,它的取值分为流式套接字SOCK_STREAM,数据报套接字SOCK_DGRAM,原始套接字SOCK_RAW
SOCK_STREAM是一个有序、可靠、面向连接的双字节流。它们是在AF_INET域中通过TCP/IP连接实现的。他们也是AF_UNIX域中常见的套接字类型。
SOCK_DGRAM是数据包服务,我们可以用它来发送最大长度固定的消息。但消息是否会被正确传递或消息是否不会乱序到达没有保证。在AF_INET域中通过UDP/IP连接实现,它提供的是一种无需的不可靠服务。
SOCK_RAW原始套接字服务。提供一个数据报接口直接访问IP层。绕过传输层协议,需要应用程序构造协议首部。
1.3 协议类型
protocol :协议类型,IPPROTO_TCP等;一般由前两个参数就决定了协议类型,设置为0即可。 通常为0,表示按给定的域和套接字类型选择默认协议。当同一域和套接字类型支持多个协议时,可以通过protocal(协议)参数 选择特定的协议。
1.4 返回值
返回值:成功返回非负整数, 它与文件描述符类似,我们把它称为套接口描述字,简称套接字。失败返回-1
2、bind函数
包含头文件<sys/socket.h>
功能:绑定一个本地地址到套接字
原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数
sockfd:socket函数返回的套接字
addr:要绑定的地址
addrlen:地址长度
返回值:成功返回0,失败返回-1
3、listen函数
包含头文件<sys/socket.h>
功能:将套接字用于监听进入的连接
原型:int listen(int sockfd, int backlog);
参数
sockfd:socket函数返回的套接字
backlog:规定内核为此套接字排队的最大连接个数
返回值:成功返回0,失败返回-1
4、accept函数
包含头文件<sys/socket.h>
功能:从已完成连接队列返回第一个连接,如果已完成连接队列为空,则阻塞。
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:服务器套接字
addr:将返回对等方的套接字地址
addrlen:返回对等方的套接字地址长度
返回值:成功返回非负整数,失败返回-1
5、connect函数
包含头文件<sys/socket.h>
功能:建立一个连接至addr所指定的套接字
原型:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数
sockfd:未连接套接字
addr:要连接的套接字地址
addrlen:第二个参数addr长度
返回值:成功返回0,失败返回-1
下图是基于TCP协议的客户端/服务器程序的一般流程,我们可以使用上述函数实现:
图2: