1.什么是socket?
socket的英文翻译就是接口,插座的意思,很形象,就相当于将2台电脑用一根线连起来,线的两头插在不同的电脑上,借此实现通讯的功能。
两台电脑通信,实际上是这两台电脑上的某个进程在进行通信。而两个进程进行通信,实际上是往同一个文件中读取数据。
2.TCP/IP(3次握手)
在tcp/ip协议中,tcp通过三次握手建立起一个tcp的链接,大致如下
第一次握手:客户端尝试连接服务器,向服务器发送syn包,syn=j,客户端进入SYN_SEND状态等待服务器确认
第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
3.在Linux下进行socket程序编写
流程图如下:
服务端的socket编程
基础的步骤如下,基本都是使用一些API函数:
(1)创建socket;
(2)绑定地址和端口;
(3)启动监听;
(4)接受客户端的请求;
(5)读写数据;
下面介绍一下每一步所使用到的API函数
1.1创建socket
mysocket = socket(int socket_family, int socket_type, int protocol);
第一个参数为socket的协议族;一般使用AF_INET,表示使用IPV4协议。
第二个参数为socket的类型,主要分为SOCK_STREAM和SOCK_DGRAM,分别对应TCP协议和UDP协议。
第三个参数为socket使用的特定协议,一般对应一个协议族就只有一个协议,可以使用0表示使用默认的协议。
函数的返回值为创建的socket文件描述符。-1表示创建失败。
1.2绑定地址和端口:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
第一个参数为刚刚创建的socket;
第二个参数是一个结构体sockaddr的指针。但实际使用的时候,根据协议的不同,而使用不同的结构。对于TCP而言,使用sockaddr_in。
第三个参数是第二个参数结构体的长度。
1.3启动监听:
int listen(int sockfd, int backlog);
第一个参数为socket文件描述符;
第二个参数为同时连接数量;
1.4接收客户端请求:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
第一个参数socket文件描述符;
第二个参数为sockaddr结构体指针,用来接收客户端的地址信息。
第三个参数为第二个参数的长度。
返回值为对应的客户端socket的文件描述符,失败则返回-1。
1.5读写操作
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
tcpserver.c
客户端的socket编程
客户端的功能,就是连接到服务器,然后就可以进行通讯。所以主要的步骤就是填写服务器的地址并进行连接。
(1)创建socket;
(2)连接服务器;
(3)读/写数据;
2.1 连接服务器
创建socket与读/写数据,和服务端的一模一样,这里只讲一下连接这一步。
函数原型:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
第一个参数为创建的socket文件描述符。
第二个参数为sockaddr结构体指针,服务器端的地址信息。
第三个参数为第二个参数的长度。
可以使用inet_addr将IP地址从字符串形式转换为二进制形式。
tcpclient.c文件
执行程序(先运行服务端,再运行客户端)