

Linux Socket编程搞不懂?,明明代码都写了却连不上。,它到底在内核里干了啥?
今天花了一整天,把Socket从创建到断开的每一步,对着内核文档、tcpdump合手的包、strace追踪的系统调用,一条一条捋明晰了。不是抄网上教程,是我方用telnet连我方写的server,看哪一步卡住,再且归查errno、看ss输出、翻《Understanding Linux Network Internals》里sock结构体那几章。累是累,但终于不再靠“背函数规则”写集会要道了。
socket调用后,其实啥也没绑,连IP和端口都莫得。就像去办手机卡,交易厅给你一张空卡(fd),但卡号还没录进系统。bind才是把号码(端口)和地址(IP)登记进内核的映射表。这里容易错:传进去的sin_port必须用htons转成集会字节序,否则事业器长久收不到包——我试过一次没转,telnet连上去凯旋超时,查了半小时才发现是字节序问题。
listen看起来是“运行监听”,本质是告诉内核:我要建两个部队。一个放刚发SYN的客户端(半承接部队),一个放SYN-ACK+ACK都回罢了、只等accept取走的承接(全承接部队)。backlog参数不是“最多接100个用户”,而是这两个部队加起来最多放这样多个。部队满了,新的SYN会被内核凯旋丢掉,客户端就卡在connect里等死。

accept复返的是个新fd,不是正本的监听fd。这点越过环节。许多东说念主合计一个fd能又接新承接又收数据,不能。监听fd就像公司前台,只认真叫东说念主进来;新fd才是具体跟客户谈业务的销售。前台和销售要分开,否则前台忙着管待,客户问问题就没东说念主办了。
{jz:field.toptypename/}recv复返0不是bug,是对方close了,TCP发来了FIN。这时候别急着退出,该回的数据还可能没发完。send也相似,它可能只发了部分数据,尤其是大包,得用while轮回查验复返值,否则一半音讯就丢了。我第一次写的时候没科罚send复返值,发1KB只发了300字节,客户端一直等剩下的,卡死了。
close不是断开承接,仅仅告诉内核:“我毋庸这个fd了”。内核发现援用计数酿成0,才真确运行发FIN,走四次挥手。是以父子程度里乱close监听fd,可能让通盘事业已而不接新承接——因为父程度close了,fd援用没了,内核干脆把监听关了。

TIME_WAIT不是卡着不汗漫,是怕集会里乱飞的旧包砸进新承接。比如客户端快速重连,端口复用,万一前次承接的延伸ACK还在路上,新承接就会收到乱序FIN,凯旋断掉。内核宁可等2MSL(最长报文存活时期),也不冒险。
多程度事业器里,fork要放在accept之后。子程度坐窝关掉监听fd,只用承接fd干活;父程度关掉承接fd,络续等下一个accept。否则父子都拿着监听fd,谁accept都行,但本质惟有一个能见效,另一个会阻拦或出错。子程度退出后,父程度不wait,就会攒一堆僵尸程度。我试过漏写wait,跑两分钟top里就十几条
调试时发现ss比netstat快得多,一瞥ss -tuln就能看清悉数监听端口;tcpdump合手包用port 8000比host过滤更准;strace -e trace=socket,bind,listen,accept,send,recv,close ./server,能看见每一步系统调用的参数和复返值,比printf调试靠谱十倍。

AF_UNIX和AF_INET看着都是socket,但地址结构体都备不相似。inet_pton比inet_addr安全,后者碰到违警字符串会复返-1还设errno,但随机候复返0又不报错,容易埋坑。当今一律用inet_pton。
socket的内容,不是“通达一个集会通说念”,而是跟内核签了一份事业协议:你请求资源,我分派fd;你绑定地址,我登记进口;你listen,我准备部队;你accept,我寄托实例。它和open、pipe相似,都是Linux把不同资源兼并成“文献描写符”的蓄意体现。
终末一句:别背函数,去合手包,去看ss,去strace,去改一瞥代码然后看它错在哪。错多了,就懂了。

家长朋友们可能因为经济的因素,或是认为听力损失太重的一侧耳,助听器已经提供不了什...
在数字化波澜席卷环球的今天,个东谈主信息的传播速率和范围达到了前所未有的高度。一...
宏润竖立集团股份有限公司(以下简称“公司”)于2026年1月23日在宏润大厦会议...
科技日报记者崔爽 近日,中国科学院工程热物理接洽所自主研制的“彩色”金属3D打印...