1.设置非阻塞套接字
unsigned long ul = 1;
ioctlsocket(socketFd, FIONBIO, &ul); //设置为非阻塞模式
2 .TCP 粘包出现原因:在流传输中出现,UDP不会出现粘包,因为它有消息边界(参考Windows 网络编程)
1 发送端需要等缓冲区满才发送出去,造成粘包
2 接收方不及时接收缓冲区的包,造成多个包接收
详细出处:http://www.52rd.com/Blog/Archive_Thread.asp?SID=22621
3.select I/O
只要某个socket在缓冲区有还有数据,select就会返回可读的选项
select超时返回0,错误-1
select(FD_SETSIZE, &m_scanSet, (fd_set *)0, (fd_set *)0, &waitTime); 当所有的检查对象个数为0时,select立即返回,如果在while循环中,则会导致CPU较高
如果检查一个无效的socket句柄0xFFFFFFFF,则每次select都会出现可读,CPU也会高
4.当接收端的接收缓冲区和发送端的发送缓冲区都满了,就无法发送数据了。发的慢有可能是接收的慢。
5.同步send()
int sendlen = send(cliSock, "china", 10, 0); 发送了10个字节,从"china"后面的内存开始继续拷贝3个字节,内容随机
6.listen()的队列大小
修改somaxconn
该内核参数默认值一般是128,对于负载很大的服务程序来说大大的不够。一般会将它修改为2048或者更大。
echo 2048 > /proc/sys/net/core/somaxconn 但是这样系统重启后保存不了
在/etc/sysctl.conf中添加如下
net.core.somaxconn = 2048
然后在终端中执行
sysctl -p
相关介绍:http://blog.csdn.net/pud_zha/article/details/8204187 ,注意已连接队列和未连接队列的概念
7.linux下socket高并发
http://www.cnblogs.com/zengkefu/p/5635081.html
8.设置接收缓冲区,发送缓冲区大小, size的单位是字节
// 接收缓冲区
int nRecvBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
(1)当设置的值val > 最大值sysctl_wmem_max,则设置为最大值的2倍:2*sysctl_wmem_max;
(2)当设置的值的两倍val*2 <最小值,则设置成最小值:SOCK_MIN_SNDBUF;
(3)当设置的值val < 最大值sysctl_wmem_max,且 val*2> SOCK_MIN_SNDBUF, 则设置成2*val。
存放接收缓冲区最大值的位置:/proc/sys/net/core/rmem_max:
存放发送缓冲区最大值的位置:/proc/sys/net/core/wmem_max:
9.查看socket缓冲区剩余没有读取的数据, 60145是端口, 还可以通过src 关键字来过滤
ss -m dport = :60145
比如接收方监听在8080端口,在接收端使用 netstat查看链路的远程端口是60145,则查看的是接收缓冲区
在发送端可以使用 sport(源端口53764), 目标dport 端口8080 (这样就能区别不同的链路了)
ss -m sport = :53764 and dport = :8080
10.Unix domain socket 比TCP/IP loopback 快约50%,
loopback之所以比远程ip要快很多,是因为传输层检测到是 loopback 地址,就会减少传输层和所有网络层的操作
https://www.cnblogs.com/sparkdev/p/8359028.html,创建domain socket:
serun.sun_family = AF_UNIX;
family 指定为 AF_UNIX,使用 AF_UNIX 会在系统上创建一个 socket 文件,不同进程通过读写这个文件来实现通信
11. netstat 查看链路状态
如果网线异常断开了,在服务端 netstat -anp|grep 显示的链路还是ESTABLISHED状态, 是"僵尸"链路,这个链路其实已经不存在了