关于TCP和UDP Socket通信的区别:
应用场景:
传输数据大小:
TCP/IP协议:
应用层、传输层、网络层、链路层
TCP和UDP都是基于TCP/IP的协议。
cat /proc/net/sockstat
sockets: used 642
TCP: inuse 1 orphan 0 tw 0 alloc 5 mem 1173
UDP: inuse 0 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0
mem表示消耗的内存,单位是Page,一般为4k,占用内存为1173 * 4 * 1024bytes
表示的是内核缓存中还没来得及被用户空间取走的内存大小。
inuse:表示正在使用(监听)的TCP socket数量。
orphan:无主(不属于任何进程)(孤儿)的Tcp 连接数(无用、待销毁)
tw:等待关闭的TCP连接数。
alloc:已分配(已建立、已申请到sk_buffer)的TCP socket数量
mem:socket缓冲区使用量,单位Page
发送缓冲区:
cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
接收缓冲区:
cat /proc/sys/net/ipv4/tcp_rmem
4096 87380 6291456
4096表示最小值
16384表示默认值
4194304表示最大值
TCP对传输数据的大小没有限制,只要不超过socket的内存缓冲区都可以,超过内存缓冲区,如果接受端没有及时去read()缓冲区的数据,那么发送端的write()无法完成,处于阻塞状态。
而Udp的数据大小,一包不能超过64K。
Tcp socket通信是可靠的传输协议,数据不会出错或者丢失,因此一般情况下不需要做数据有效性的校验。可是有人担心,在网络特别差的时候,socket数据发送会失败,这种情况,Tcp socket程序是会报错的,报socket相关读写错误。
而UDP socket通信,是不可靠的传输协议,会导致传输的数据丢包出错等现象,但是UDP不会有提示,所以UDP通信需要去做数据有效性的校验。
因为Tcp socket通信是面向流的传输协议,而UDP 是面向消息的传输。
所以在Tcp socket中,当发送速度特别快,而接收端接收速度跟不上时,就会出现粘包的问题。即接收端一次读出多包数据或者读出两包数据的个一部分。而UDP不会出现这种情况。
所以,Tcp socket需要解决的最大问题可能是粘包问题。
adb shell cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
adb shell cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
adb shell cat /proc/sys/net/ipv4/tcp_keepalive_probes
9
keepalive routine每2小时(7200秒)启动一次,发送第一个probe(探测包),如果在75秒内没有收到对方应答则重发probe,当连续9个probe没有被应答时,认为连接已断。
//建立socket连接
mSocket = new Socket(“127.0.0.1”, 9897);
//设置发送逗留时间2秒 ; 中断后未传输数据可传输的时间(秒),defalut false
mSocket .setSoLinger(true, 2);
//设置InputStream上调用 read()阻塞超时时间2秒
mSocket .setSoTimeout(2000);
//设置socket发包缓冲为32k;
mSocket .setSendBufferSize(32*1024);
//设置socket底层接收缓冲为32k
mSocket .setReceiveBufferSize(32*1024);
//关闭Nagle算法.立即发包
mSocket .setTcpNoDelay(true);
//设置客户端 socket 关闭时,close() 方法起作用时延迟 30 秒关闭,在 30 秒内尽量将未发送的数据包发送出去
mSocket .setSoLinger(true, 30);
//防止服务器端无效时,客户端长时间处于连接状态
mSocket.setKeepAlive(true);
//该数据不经过输出缓冲区,立即发送,可用来做心跳包
mSocket.sendUrgentData(0x44); //”D”
总结:
1、socket输出流和输入流,OutputStream和InputStream,outputStream close后,所在的socket也就close了。