一、Socket理解
1、在Tcp/IP协议中,Socket即为套接字,简单点来说,就是用来唯一标识网络通讯中的一个进程。为“IP地址+TCP或UDP端口号”,这个标识的全部组成,就叫做套接字
2、在TCP协议中,客户端和服务器端,各自会生成一个套接字来将两个进程连接起来。那么这个Socket Pair 就用来唯一标识这个连接
3、Socket 可以形象用来形容网络中一对一的关系,所以在TCP/IP协议中,应用层编程接口称为Socket API
综合来说,Socket套接字就是用量描述IP地址和端口,是通信链的句柄,应用程序可以通过Socket向网络发送请求或者应答网络请求!Socket是支持TCP/IP协议的网络通信的基本操作单元,是对网络通信过程中端点的抽象,包含了进行网络通信所必须的五种信息,连接所使用的协议,本机主机的IP地址,本地远程的协议端口,远程主机的IP地址以及远程进程的端协议端口
二、客户端和服务器端建立连接的过程
从服务器端:先调用socket()方法创建一个套接字来通讯,然后绑定这个文件的描述符,调用listen()来监听端口是否有客户端请求来,如果有请求产生,accept()进行连接,建立完整的连接之后就可以进行通讯。
从客户端而言:调用socket()方法分配一个用来通讯的端口,接着继续调用connect()发出SYN请求并处于阻塞状态的,然后服务器应答一个SYN-ACK,客户端收到后从conncet()返回,ACK分段,服务器收到后从accept()返回,连接建立成功,客户端一般不调用bind()来绑定一个端口号,所以说并不是不允许bind(),服务器也不是必须要bind()。
TCP服务器端编程一般步骤:
1、用socket()函数创建一个socket
2、用setsocket()函数设置socket的属性值
3、用bind()函数绑定IP地址、端口等信息到socket上
4、创建设置好基本信息之后,用listen()函数开启监听
5、用accept()函数接受客户端发送上来的连接
6、通过运用send()和recv()或者read()和write()进行数据的收发
7、完成数据收发后,关闭网络连接
8、继续关闭监听设置
TCP客户端编程一般步骤:
1、和服务器端一样,用socket()函数创建一个socket(也就是套接字)
2、同样也要设置socket的属性值,我们通过setsocket函数在实现
3、既然要实现通讯,那么需要用bind()函数绑定IP地址、端口属性到socket上面
4、设置连接的对方的IP地址和端口等属性
5、用connect()函数连接服务器
6、通过运用send()和recv()或者read()和write()进行数据的收发
7、关闭网络连接之后,标志与服务器端的通讯结束
###我们在这里思考一个问题:
为什么不建议客户端进行bind()?
当客户端没有自己进行bing时,系统随机分配给客户端一个端口号,并且在分配的时候,操作系统会做到不与现有的端口号发生冲突,但如果自己进行bind,客户端程序就容易出现问题,我们可以这样假设,在一个PC机上开启多个客户端进程,如果是用户自己绑定了端口号,必然会造成端口冲突,从而影响通讯。
三、TCP协议连过程
在TCP连接完成后,进行数据传输,数据肯定是通过网卡流入,然后通过DMA的方式拷贝到recv buffer中,通过recv()函数从其中拷贝到app buffer中。
四、基于TCP通讯协议的socket通信
具体案例分析可以参考https://www.runoob.com/w3cnote/android-tutorial-socket1.html
对TCP协议和socket通信有不错的解释和案例说明,是基于Java的项目。