关于TCP和UDP Socket通信的区别:

应用场景:

  • UDP传输协议效率高,但不可靠;
  • TCP传输效率低,但可靠。

传输数据大小:

  • UDP传输数据限定在64K以下;
  • TCP传输数据无大小限制,可进行大数据传输。

TCP/IP协议:
应用层、传输层、网络层、链路层

TCP和UDP都是基于TCP/IP的协议。

1、查看TCP/UDP数据占用内存大小

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

2、系统内核socket缓冲区

发送缓冲区:

cat /proc/sys/net/ipv4/tcp_wmem
4096    16384   4194304

接收缓冲区:

cat /proc/sys/net/ipv4/tcp_rmem
4096    87380   6291456

4096表示最小值
16384表示默认值
4194304表示最大值

3、传输数据大小

TCP对传输数据的大小没有限制,只要不超过socket的内存缓冲区都可以,超过内存缓冲区,如果接受端没有及时去read()缓冲区的数据,那么发送端的write()无法完成,处于阻塞状态。

而Udp的数据大小,一包不能超过64K。

4、数据可靠性

Tcp socket通信是可靠的传输协议,数据不会出错或者丢失,因此一般情况下不需要做数据有效性的校验。可是有人担心,在网络特别差的时候,socket数据发送会失败,这种情况,Tcp socket程序是会报错的,报socket相关读写错误。

而UDP socket通信,是不可靠的传输协议,会导致传输的数据丢包出错等现象,但是UDP不会有提示,所以UDP通信需要去做数据有效性的校验。

5、Tcp socket通信粘包问题

因为Tcp socket通信是面向流的传输协议,而UDP 是面向消息的传输。

所以在Tcp socket中,当发送速度特别快,而接收端接收速度跟不上时,就会出现粘包的问题。即接收端一次读出多包数据或者读出两包数据的个一部分。而UDP不会出现这种情况。

所以,Tcp socket需要解决的最大问题可能是粘包问题。

6、TCP的KEEPALIVE功能

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没有被应答时,认为连接已断。

7、Android Socket基本用法

//建立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了。