网络学习七

概述

本章主要实现的程序模型:


2 TCP回射服务器程序

服务器与客户程序约定一个固定的端口,要比5000大,比49152小。
fork后子进程第一件事就是关掉listenfd,父进程的第一件事是关掉connfd。
在等待客户的read调用返回出错后,如果是因为被信号打断,要重新调用read。

正常情况

正常启动
监听套接字处于LISTEN状态。
客户的connect在三路握手的第二个分节就返回了,而服务器要直到第三个分节才返回,即客户的connect返回时服务器还没有accept。
服务器的连接套接字处于ESTABBLISHED状态。
正常终止
客户端主动关闭时,客户TCP发送一个FIN给服务器,服务器TCP响应ACK,此时服务器处于CLOSE_WAIT状态,客户处于FIN_WAIT_2状态。
服务器关闭时,服务器发送FIN给客户,客户发送ACK给服务器,连接完全终止,客户进入TIME_WAIT状态。
服务器子进程终止时给父进程发送一个SIGCHLD信号。默认行为是忽略,但我们必须捕捉此信号,清理僵死进程。

POSIX信号处理

信号是某个进程发生了某个事件的通知,有时也称为软件中断,通常是异步发生的,也就是说进程预先不知道信号的准确发生时刻。
信号可以:
由一个进程发给另一个进程
由内核发给某个进程
每个信号都有一个与之关联的处置也称行为。

处理SIGCHLD信号

多进程下父进程必须捕捉SIGCHLD信号以回收终止状态的子进程资源,否则进程处于僵尸状态。可以在信号处理函数中用wait或waitpid。慢速系统调用会被信号处理函数打断,可能会返回EINTR错误,也可能会自动重启。我们编写捕获信号的程序时,必须对此有所准备。例如,对accept的处理,connect被打断后就不能被使用了。

wait和waitpid函数

通过wait和waitpid都可以获得终止的子进程的pid和状态,waitpid还能指定想等待的pid,options参数允许指定附加选项,最常用的是WNOHANG,在没有终止子进程时不阻塞。
信号阻塞期间如果该信号产生了多次,解除阻塞后只能接收到一次,因此要用waitpid(-1,*,WNOHANG)来循环回收所有结束的子进程。

accept返回前连接中止

三路握手完成,连接建立后,客户TCP发送了RST,服务器端在调用accept前收到了这个RST。
如何处理这种中止依赖于不同的实现。BSD的实现是在内核中处理,服务器的accept继续阻塞,SVR4的实现是返回一个错误给进程。如果返回了一个错误,再次调用accept就行。

服务器进程终止

客户与服务器连接成功后,服务器进程如果终止(被动),套接字被关闭,向客户发送FIN,客户响应ACK,此时客户进程可能阻塞在用户输出上,看不到这个RST,此时如果进行write,再read,就会收到预期外的EOF。

SIGPIPE信号

写一个已收到FIN的套接字会收到RST,写一个已收到RST的套接字会产生SIGPIPE信号。
如果没有特殊的事情要做,就将SIGPIPE设置为SIG_IGN,忽略它,并在后面的读写操作中检查返回的错误。如果需要采取特殊措施(如写入日志),就要捕捉该信号。但如果用了多个套接字,信号处理程序无法分辨是哪个套接字出的错。如果需要知道出错的位置,要么不理会该信号,要么从信号处理函数返回后再处理write的EPIPE。

服务器主机崩溃 服务器主机关机

服务器主机崩溃时,已有的网络连接上不发出任何东西(如FIN)。客户对服务器的写操作会持续重传数据,试图接收一个ACK,直到超时。客户随后的readline调用会返回一个错误。
可以对readline设置一个超时。如果不主动向服务器发送数据也想检测出服务器主机的崩溃,需要SO_KEEPALIVE套接字选项。

服务器主机崩溃后重启

服务器主机在崩溃后客户发数据前重启完成,客户不知道服务器主机的崩溃,发送数据,但服务器TCP丢失了之前的连接信息,因此响应RST,客户TCP收到RST时,客户进程正阻塞于readline调用,该调用返回一个错误。

数据格式

例子:在客户与服务器之间传递文本串
用sscanf获取文本中的指定数据,再用snprintf把结果转换为文本串。
例子:在客户与服务器之间传递二进制结构
当这样的客户和服务器程序运行在字节序不一样的或某些类型长度不一致的两个主机上时,工作将失常。
不同的实现在存储二进制数据的格式上(大端小端)、相同类型的长度上、给结构打包的方式(对齐)上都可能不同,因此直接传送二进制结构绝不明智。
解决方法:

  1. 所有的数值数据作为文本串来传递。
    
  2. 显式定义所支持数据类型的进进制格式,并以这样的格式在客户与服务器间传递所有数据。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容

  • 1、TCP状态linux查看tcp的状态命令:1)、netstat -nat 查看TCP各个状态的数量2)、lso...
    北辰青阅读 9,423评论 0 11
  • 最近在看《UNIX网络编程 卷1》和《FREEBSD操作系统设计与实现》这两本书,我重点关注了TCP协议相关的内容...
    腩啵兔子阅读 1,164评论 0 7
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,652评论 18 139
  • 《UNIX 网络编程卷一:套接字联网API》笔记 套接字 套接字编程接口,是在 TCP/IP 协议族中,应用层进入...
    超net阅读 5,798评论 2 13
  • 18.1 引言 TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。本章将...
    张芳涛阅读 3,378评论 0 13