网络流常见模型与技巧

sto louis & Maverik orz!

写一些知识点,图论杂题过后单独开一篇。(upd: 高估了图论杂题的数量,看起来凑不够一篇,那不开了。

最小割

最大流最小割定理

对于任意网络 G = ( V , E ) G = (V, E) G=(V,E) ,其上的最大流 f f f 和最小割 { S , T } \{S, T\} {S,T} 总是满足 ∣ f ∣ = ∣ ∣ S , T ∣ ∣ |f| = ||S, T|| f=∣∣S,T∣∣
即,最大流在数值上等于最小割。

最小割的可行边与必须边

同一个网络的最小割有多种可行的方案,我们需要对一条割边的可行性与必要性进行讨论。
可行边: 指存在于任意可行割集中的的边。
必须边: 指存在于所有可行割集中的的边。

可行边

一条边 u → v u\to v uv 作为最小割的可行边的充要条件是:

  • 这条边满流
  • S C C u ≠ S C C v SCC_u\neq SCC_v SCCu=SCCv

第一条限制的必要性是显然的,我们来证明第二条限制。
u u u v v v 不在同一强连通分量,等价于残量网络上不存在一条从 u u u v v v 的路径。如果存在一条从 u u u v v v 的路径,就会和 u → v u\to v uv 满流后形成的反向边构成环,破坏了最大流的性质, u → v u\to v uv 必然不能是可行边。

必须边

一条边 u → v u\to v uv 作为必须边的充要条件是:

  • 首先它是一条可行边
  • S C C s = S C C u , S C C v = S C C t SCC_s=SCC_u,SCC_v=SCC_t SCCs=SCCu,SCCv=SCCt

后者等价于残量网络上同时存在 s → u s\to u su v → t v\to t vt 的路径。如果不存在,则说明只割掉前面(或后面)所有满流的边就能令 s s s u u u 不连通(或 v v v t t t),这样 u → v u\to v uv 就不是必须要割的边。

最大权闭合子图

闭合图:一个有向图的子图,满足若一个点在该子图内,则它的所有后继节点都在该子图内。
最大权闭合子图:一个带点权的有向图,点权有正有负,求一个闭合子图的权值和的最大值。

做法

这是一个较为经典的问题。
考虑如下的建图:将点按照点权的正负分为正值点和负值点。源点向所有正值点连边,容量为点权;所有负值点向汇点连边,容量为点权的绝对值。在正负值点之间按照原图连边,容量为 inf ⁡ \inf inf

答案为正值点的权值和减去原图的最小割。

证明

考虑这样建边的实际意义,设 s → i s\to i si 的边不割表示选了这个正值点, i → t i\to t it 的边不割表示不选这个负值点。
那么 s → t s\to t st 连通就表示选了某个正值点但没选它后继的负值点,于是寄了。我们的目标是用最小的代价让它们不连通,这就是求最小割。
为什么不用反过来考虑呢?因为如果一个负值点被选,一定因为它是某个正值点的后继而不得不选。所以选的第一个点一定是正的。

CF311E Biologist

不会做 *2300 /oh。
首先完不成要倒扣的限制可以通过把达成条件的奖励加 g g g 来消去。然后对求的东西进行转化,最大化利润等价于最小化未获得的奖励+成本。
因此这样建图:

  • S i = 0 S_i=0 Si=0,连边 ( i , t , v i ) (i,t,v_i) (i,t,vi),割掉该边表示选 1 1 1 要花费 v i v_i vi 的代价;否则连边 ( s , i , v i ) (s,i,v_i) (s,i,vi)
  • 对每条限制开一个新点。如果限制是全为 1 1 1,即限制某些位置不能有 0 0 0,连边 ( s , j , w j ) (s,j,w_j) (s,j,wj) ( j , x , inf ⁡ ) (j,x,\inf) (j,x,inf);否则连边 ( j , t , w j ) (j,t,w_j) (j,t,wj) ( x , j , inf ⁡ ) (x,j,\inf) (x,j,inf)。如果割开限制边,则表明该奖励没有被达成。

这样建图可以保证一个点不会既满足 0 0 0 限制又满足 1 1 1 限制,因为这样这两个限制的边会通过这个点连通。

混合图的欧拉回路 Euler Circuit

与有向图、无向图的欧拉回路不同,在混合图中,我们需要对所有无向边进行合理的定向,使之转化为有向图求解。

先对所有边随机指定一个方向,令点的权值 d i = i n i − o u t i d_i=in_i-out_i di=iniouti。我们希望通过调整边的方向,使所有 d i = 0 d_i=0 di=0
考虑将原本 u → v u\to v uv 的边反向,对 d d d 数组的影响是 d u ← d u + 2 , d v ← d v − 2 d_u\gets d_u+2,d_v\gets d_v-2 dudu+2,dvdv2。因此我们把 d d d 数组全部除以 2 2 2,一次反向操作的贡献变为 1 1 1
对于 d i > 0 d_i>0 di>0,连边 ( s , i , d i ) (s,i,d_i) (s,i,di);对于 d i < 0 d_i<0 di<0,连边 ( i , t , − d i ) (i,t,-d_i) (i,t,di)。对于原图的每条无向边 u → v u\to v uv,连边 ( u , v , 1 ) (u,v,1) (u,v,1)。跑最大流,流满的边即为需要反向的边。

对所有边定向完毕后,跑有向图的欧拉回路即可。

费用流

那个长得神似 Dinic 的费用流其实叫 zkw 费用流。

[CQOI2012] 交换棋子

网络流题总是能写出层出不穷的假做法,怎么办呢。
忽略掉所有白棋子,那么问题相当于每次可以八连通移动,将黑棋子移动到指定的位置。次数限制在方格上,考虑拆点,连边 ( i n x , y , o u t x , y , l i m i t , 0 ) (in_{x,y},out_{x,y},limit,0) (inx,y,outx,y,limit,0) l i m i t limit limit 是交换次数限制的一半,特判下奇数且初始/终止为黑的点。
对于初始位置的黑棋子,连边 ( s , i n x , y , 1 , 0 ) (s,in_{x,y},1,0) (s,inx,y,1,0);对于终止位置的黑棋子,连边 ( o u t x , y , t , 1 , 0 ) (out_{x,y},t,1,0) (outx,y,t,1,0)。每个格子向八连通位置连费用为 1 1 1 的边,表示交换,跑费用流。

然后这个假了,原因是要特判某个位置一开始就是黑的,最后还是黑的。这种情况不应当连边,因为它一直不动的话没有交换次数,不会贡献大小为 1 1 1 的流。

[NOI2012] 美食节

P2053 的加强版。这人怎么不仅不会网络流,还不会拆贡献 /cf
发现做每个菜的贡献跟前面做菜的总时间有关,试图倒过来考虑。设第 i i i 个菜是第 j j j 个厨师倒数第 k k k 个做的,它对答案的贡献是 T i , j × k T_{i,j}\times k Ti,j×k
至此,不同菜或厨师之间的贡献独立。比较暴力的做法是直接把每个厨师拆成 p p p 个点,分别表示这个人倒数第几次做菜,跑费用流,可以通过 P2053。

不过发现,我们只有先做了倒数第 i i i 个菜,才有可能做倒数第 i + 1 i+1 i+1 个菜,否则一定不优。因此可以在 dinic 的过程中动态加边,每次增广后判断,等到倒数第 i i i 个已经被选,再连边第 i + 1 i+1 i+1 个。这里要每次增广就判断一次,而不是全部增广完毕再加边。后者会使图中出现负环。

[WC2007] 剪刀石头布

双倍经验:CF1264E Beautiful League

直接对三元环计数,发现没法做。反过来对无法形成环的三元组进行计数,那么目标是最小化这样的三元组数量。

考虑一个无法形成环的三元组有什么性质,发现它有且仅有一个点出度为 2 2 2。同时我们发现这是判定一个三元组非法的充要条件,所以我们要对这样的一个点和两条边数数。

d e g i deg_i degi 表示点 i i i 的出度,那么点 i i i 对应的非法三元组数量为 d e g i ( d e g i − 1 ) 2 \frac{deg_i(deg_i-1)}{2} 2degi(degi1)。问题转化为给所有无向边定向,最小化 ∑ i = 1 n d e g i ( d e g i − 1 ) 2 \sum\limits_{i=1}^n \frac{deg_i(deg_i-1)}{2} i=1n2degi(degi1)

给无向边 ( u , v ) (u,v) (u,v) 定向,要么使 d e g u ← d e g u + 1 deg_u\gets deg_u+1 degudegu+1,要么使 d e g v ← d e g v + 1 deg_v\gets deg_v+1 degvdegv+1。二选一,考虑费用流。

注意到贡献是二次的,考虑将 d e g i deg_i degi 增加 1 1 1 的代价差分。差分数组是递增的,这满足了费用流的贪心性质,也就是说满流的边一定是差分数组的一个前缀。至此我们可以用左侧一排点表示未定向的边,右侧一排点表示原图点的 d e g deg deg 值,建图:

  • 连接源点和左侧点,容量为 1 1 1,费用为 0 0 0,表示这条边对 d e g deg deg 造成总量为 1 1 1 的贡献;
  • 连接表示边 ( u , v ) (u,v) (u,v) 的左侧点和表示点 u , v u,v u,v 的右侧点,容量为 1 1 1,费用为 0 0 0,表示 ( u , v ) (u,v) (u,v) 可以对两个点产生贡献;
  • 在每个右侧点和汇点之间连 n n n 条边,容量为 1 1 1,费用分别为 d e g deg deg 数组从 0 0 0 n − 1 n-1 n1 的差分。

答案为 n ( n − 1 ) ( n − 2 ) 3 ! − m i n c o s t \frac{n(n-1)(n-2)}{3!}-mincost 3!n(n1)(n2)mincost

二分图匹配 & 偏序集

时间复杂度

匈牙利是 O ( n m ) O(nm) O(nm),Dinic 是 O ( n m ) O(\sqrt{n}m) O(n m)

可行边与必须边

可行边:在图上满流,或 S C C u = S C C v SCC_u=SCC_v SCCu=SCCv
必须边:在图上满流,且 S C C u ≠ S C C v SCC_u\neq SCC_v SCCu=SCCv

注意这里的条件与最小割的区别。

证明

假设我们已经得到了一组解。如果这个图上存在某条长度为偶数的交错路,把这条路上的所有边状态取反不改变答案。因此属于一条长度为偶数的交错路的匹配边均是可行边,且不是必须边。这等价于在残量网络中 S C C u = S C C v SCC_u=SCC_v SCCu=SCCv

而必须边即为排除掉上述情况的可行边。

Kőnig 定理

最小点覆盖:选最少的点,满足每条边至少有一个端点被选。

二分图中,最小点覆盖 = 最大匹配。

解的构造

显然我们只要找到一种构造方式就证明了这个定理,因此下文仅叙述如何构造出一组合法解。
我们先求出当前二分图的最大匹配,并记录匹配边。

接下来,从右侧的所有非匹配点遵循如下规则开始 dfs,并标记所有经过的点:

  • 右部点只能通过非匹配边向左走;
  • 左部点只能匹配边向右走。

我们取左侧被访问过的点和右侧未被访问过的点,它们的并集为一个合法解。

证明

首先,右侧的非匹配点一定都被 dfs 到了,加入答案的一定是匹配点。
而右侧被 dfs 到的匹配点一定是因为与之匹配的左侧点被 dfs 到了,那么这条边的左端点已经被选入了最小点覆盖。
左侧的非匹配点一定不会被 dfs 到,否则我们可以让走向它的右部点与之匹配,不满足二分图最大匹配的性质。

那么我们得出结论:只有匹配边的端点会被选上,且每条匹配边的端点恰好被选了一个。

接下来证明这组解覆盖了所有的边。
只有出现左部点未被 dfs 到且右部点被 dfs 到的情况,才会两个端点都不被覆盖。根据是否是匹配边分讨一下,发现这显然是不可能的。因此我们构造出的解合法,且总点数最小。

最大独立集

最大独立集:选最多的点,满足两两之间没有边相连。

二分图的最大独立集 = 总点数 - 最小点覆盖。

解的构造

二分图的最大独立集是最小点覆盖的补集。

可以根据定义证明:最小点覆盖是每条边只要一个端点被选,那么它的补集就是每条边至多有一个端点被选,即最大独立集。

最大团等于总点数减去补图的最大独立集。

[HAOI2017] 新型城市化

在补图上考虑问题。由于题目保证了原图可以划分为不超过两个团,这条性质等价于补图至少可以划分为两个独立集,进一步等价于补图是一个二分图。
我们的目标变成:在二分图上删一条边,判断最大独立集是否变大。
根据最大独立集的性质,我们判断的就是最大匹配是否减小,即判断哪些边是二分图最大匹配的必须边。可以利用上面的结论,先跑 dinic,再在残量网络上跑一遍 tarjan 求出答案。

偏序集

定义

偏序集:集合中部分元素可以比较大小。
全序集:集合中所有元素都可以比较大小。
链:全集的一个子集满足其是全序集。
反链:全集的一个子集满足所有元素都不可以比较大小。
链覆盖:若干的链的并集满足是全集,且两两之间没有交集。反链覆盖同理。
最长链:所有链中元素个数最多的集合,最长反链同理。

最小不可重链覆盖

因为不可重覆盖,可以将每个点拆为一个入点和一个出点。在两类点之间按照原图连边。
跑二分图最大匹配即可,答案为总点数减去最大匹配。

最小可重链覆盖

通常有三种办法(摘自 PPT):

  • 跑传递闭包后转为不可重覆盖,可重路径一定能在新图上对应一组不重路径。
  • 同样是拆点,设分别为 a i , b i a_i,b_i ai,bi,先连源汇点,然后 a i → b i a_i\to b_i aibi 下界为 1 1 1,原图的边连上 b j → a i b_j\to a_i bjai,所有边上界均
    inf ⁡ \inf inf,跑上下界最小流即可。
  • 还是拆点,考虑改造一下不可重复覆盖的二分图,先连源汇点,上界均为 1 1 1 b i → a i b_i\to a_i biai 上界为 inf ⁡ \inf inf,原图的边
    a i → b j a_i\to b_j aibj 上界为 inf ⁡ \inf inf,这样就相当于在二分图上跑传递闭包了。

Dilworth 定理

一个偏序集中的最长反链大小,等于其中最小不可重链覆盖大小。

推论:一个 DAG 中最长反链的大小,等于其中最小可重链覆盖大小。

DAG 上最长反链的构造

模板:[CTSC2008] 祭祀

首先对 DAG 跑传递闭包,转为偏序集。拆点,转为二分图,并构造其最大独立集 I I I
那么我们取出所有 x i n ∈ I x_{in}\in I xinI x o u t ∈ I x_{out}\in I xoutI 的点 x x x,它们构成原图的最长反链。
换句话讲:取出所有 x i n x_{in} xin 被 dfs 到,且 x o u t x_{out} xout 未被 dfs 到的点,这些点组成了 DAG 的最长反链。

证明略。

CF1630F Making It Bipartite

因为倍数关系有传递性,如果有边 a → b , b → c a\to b,b\to c ab,bc,则一定有边 a → c a\to c ac。这样就会形成长度为 3 3 3 的奇环,不满足二分图的性质。
也就是说,图上的任意一个点不能既有入度又有出度,否则不合法。

考虑将一个点 x x x 拆成 x 0 x_0 x0 x 1 x_1 x1,分别表示 x x x 只有入度或只有出度。那么目标是找出若干对不能同时选的点,在它们之间连边,能够保留的点数即为这个图的最大独立集。
这个貌似不好直接求,但发现原图本身是一个偏序集,因此可以将我们自己建的图也定向成偏序集,求它的最长反链。

具体地, x 0 x_0 x0 x 1 x_1 x1 不能一起选,故连边 x 0 → x 1 x_0\to x_1 x0x1
如果 a y a_y ay a x a_x ax 的倍数,除了 ( x 1 , y 0 ) (x_1,y_0) (x1,y0) 以外任意两点都不能一起选,连边 x 0 → y 0 , x 0 → y 1 , x 1 → y 1 x_0\to y_0,x_0\to y_1,x_1\to y_1 x0y0,x0y1,x1y1

上下界网络流

感觉没啥用。摆了。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
previous up contents next C 语言常见问题集 原著:Steve Summit 翻译:朱群英, 孙 云 修订版 0.9.4, 2005年6月23日 版权所有 © 2005 * 目录 * 1. 前言 * 2. 声明和初始化 o 2.1 我如何决定使用那种整数类型? o 2.2 64 位机上的 64 位类型是什么样的? o 2.3 怎样定义和声明全局变量和函数最好? o 2.4 extern 在函数声明中是什么意思? o 2.5 关键字 auto 到底有什么用途? o 2.6 我似乎不能成功定义一个链表。我试过 typedef struct { char *item; NODEPTR next; } *NODEPTR; 但是编译器报了错误信息。难道在C语言中一个结构不能包含指向自己的指针吗? o 2.7 怎样建立和理解非常复杂的声明?例如定义一个包含 N 个指向返回指向字符的指针的函数的指针的数组? o 2.8 函数只定义了一次, 调用了一次, 但编译器提示非法重定义了。 o 2.9 main() 的正确定义是什么? void main() 正确吗? o 2.10 对于没有初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为 ``零", 它可否作为空指针或浮点零? o 2.11 代码 int f() { char a[] = "Hello, world!";} 不能编译。 o 2.12 这样的初始化有什么问题?char *p = malloc(10); 编译器提示 ``非法初始式" 云云。 o 2.13 以下的初始化有什么区别?char a[] = "string literal"; char *p = "string literal"; 当我向 p[i] 赋值的时候, 我的程序崩溃了。 o 2.14 我总算弄清除函数指针的声明方法了, 但怎样才能初始化呢? * 3. 结构、联合和枚举 o 3.1 声明 struct x1 { ...}; 和 typedef struct { ...} x2; 有什么不同? o 3.2 为什么 struct x { ...}; x thestruct; 不对? o 3.3 一个结构可以包含指向自己的指针吗? o 3.4 在 C 语言中实现抽象数据类型什么方法最好? o 3.5 在 C 中是否有模拟继承等面向对象程序设计特性的好方法? o 3.6 我遇到这样声明结构的代码: struct name { int namelen; char namestr[1];}; 然后又使用一些内存分配技巧使 namestr 数组用起来好像有多个元素。这样合法和可移植吗? o 3.7 是否有自动比较结构的方法? o 3.8 如何向接受结构参数的函数传入常数值? o 3.9 怎样从/向数据文件读/写结构? o 3.10 我的编译器在结构中留下了空洞, 这导致空间浪费而且无法与外部数据文件进行 "二进制" 读写。能否关掉填充, 或者控制结构域的对齐方式? o 3.11 为什么 sizeof 返回的值大于结构的期望值, 是不是尾部有填充? o 3.12 如何确定域在结构中的字节偏移? o 3.13 怎样在运行时用名字访问结构中的域? o 3.14 程序运行正确, 但退出时却 ``core dump''了,怎么回事? o 3.15 可以初始化一个联合吗? o 3.16 枚举和一组预处理的 #define 有什么不同? o 3.17 有什么容易的显示枚举值符号的方法? * 4. 表达式 o 4.1 为什么这样的代码: a[i] = i++; 不能工作? o 4.2 使用我的编译器,下面的代码 int i=7; printf("%d\n", i++ * i++); 返回 49?不管按什么顺序计算, 难道不该打印出56吗? o 4.3 对于代码 in
说明--TCPIP高效编程:改善网络程序的44个技巧 PDF中文版带书签-目录 下载链接放在文档中 《TCP/IP高效编程:改善网络程序的44个技巧》是TCP/IP 领域历久弥新的经典著作,网络编程人员必备,对TCP/IP 网络编程中存在的各种问题进行了全面解析,旨在帮助读者深入透彻地理解TCP/IP 网络编程。本书组织方式比较特别,正文部分包括4 章,将网络编程中存在的常见问题组织成44 个技巧,探讨问题的过程中构建并运行了多个程序,并且指出了代码的源地址,便于读者查看。全书以技巧的形式解答了日常工作中遇到的经典问题,将本书作为手册使用,极其方便。 《TCP/IP高效编程:改善网络程序的44个技巧》主要面向有一定经验的初学者或中级网络程序员,也可作为计算机相关专业人士的参考读物。 ================ 原书名:Effective TCP/IP Programming: 44 Tips to Improve Your Network Programs 原出版社: Addison-Wesley Professional 作者: (美)Jon C. Snader 译者: 陈涓 赵振平 作译者 Jon C.Snader:TCP/IP专家,Paradigm 4的资深软件工程师。他的工作领域包括通信、网络、编译器开发、操作系统以及无线网络控制器等。最近主要从事公共安全市场的报文交换系统方面的工作。 陈涓 1997年毕业于南京通信工程学院,获得通信与信息系统方向硕士学位。留校任教至今,从事网络应用方面的工作。 赵振平 1998年毕业于南京大学计算机科学系,获得操作系统和网络方向硕士学位。目前任职于南京信风软件有限公司(www.greatbit.com),从事网络安全和多媒体方面的工作。 目录 《TCP/IP高效编程:改善网络程序的44个技巧》 第1章 概述 1 1.1 几个约定 1 1.2 本书其余部分的内容介绍 2 1.3 客户端—服务器结构 4 1.4 对基本套接字API的回顾 5 1.5 小结 12 第2章 基本概念 13 2.1 技巧1:理解面向连接和无连接协议之间的区别 13 2.2 技巧2:理解子网和CIDR的概念 18 2.2.1 分类编址 18 2.2.2 子网划分 21 2.2.3 CIDR 26 2.2.4 子网划分和CIDR的状态 27 2.2.5 小结 27 2.3 技巧3:理解私有地址和NAT 28 2.4 技巧4:开发并使用应用程序“框架” 30 2.4.1 TCP服务器框架 31 2.4.2 TCP客户端框架 36 2.4.3 UDP服务器框架 38 2.4.4 UDP客户端框架 39 2.4.5 小结 41 2.5 技巧5:套接字接口比XTI/TLI更好用 41 2.6 技巧6:记住,TCP是一种协议 43 2.7 技巧7:不要低估TCP的性能 50 2.7.1 UDP源程序与接收程序 52 2.7.2 TCP源程序及接收程序 53 2.7.3 小结 59 2.8 技巧8:避免重新编写TCP 59 2.9 技巧9:要认识到TCP是一个可靠的,但并不绝对可靠的协议 61 2.9.1 可靠性——是什么,不是什么 61 2.9.2 故障模式 63 2.9.3 网络中断 63 2.9.4 对等实体崩溃 64 2.9.5 对等实体的主机崩溃 68 2.9.6 小结 69 2.10 技巧10:记住,TCP/IP不是轮询的 69 2.10.1 保持活跃 70 2.10.2 心跳信号 71 2.10.3 另一个例子 76 2.10.4 小结 81 2.11 技巧11:提防对等实体的不友好动作 81 2.11.1 检测客户端的终止 82 2.11.2 检测无效输入 84 2.11.3 小结 88 2.12 技巧12:成功的LAN策略不一定能推广到WAN中去 88 2.12.1 性能问题举例 88 2.12.2 隐含错误举例 89 2.12.3 小结 93 2.13 技巧13:了解协议是怎样工作的 93 2.14 技巧14:不要把OSI七层参考模型太当回事 94 2.14.1 OSI模型 95 2.14.2 TCP/IP模型 96 2.14.3 小结 98 第3章 构建高效且健壮的网络程序 99 3.1 技巧15:理解TCP的写操作 99 3.1.1 从应用程序的角度看写操作 99 3.1.2 从TCP角度看写操作 100 3.1.3 小结 103 3.2 技巧16:理解TCP的有序释放操作 103 3.2.1 shutdown调用 104 3.2.2 有序释放 106 3.2.3 小结 110 3.3 技巧17:考虑用inetd来装载应用程序 111 3.3.1 TCP服务器 111 3.3.2 UDP服务器 114 3.3.3 小结 118 3.4 技巧18:考虑用tcpmux为服务器“分配”知名端口 118 3.5 技巧19:考虑使用两条TCP连接 126 3.5.1 单连接结构 127 3.5.2 双连接架构 128 3.5.3 小结 133 3.6 技巧20:使应用程序成为事件驱动的(1) 133 3.7 技巧21:使应用程序成为事件驱动的(2) 140 3.8 技巧22:不要用TIME-WAIT暗杀来关闭一条连接 147 3.8.1 它是什么 147 3.8.2 为什么要使用它 149 3.8.3 TIME-WAIT暗杀 150 3.8.4 小结 151 3.9 技巧23:服务器应该设置SO_REUSEADDR选项 151 3.10 技巧24:可能的话,使用一个大规模的写操作,而不是多个小规模的写操作 155 3.10.1 禁用Nagle算法 158 3.10.2 将写操作合并起来 159 3.10.3 小结 161 3.11 技巧25:理解如何使connect调用超时 162 3.11.1 使用告警 162 3.11.2 使用select 164 3.11.3 小结 167 3.12 技巧26:避免数据复制 167 3.12.1 共享内存缓冲区 168 3.12.2 一个共享内存缓冲区系统 169 3.12.3 一个UNIX实现 171 3.12.4 一个Windows实现 175 3.12.5 小结 179 3.13 技巧27:使用前将结构sockadddr_in清零 179 3.14 技巧28:不要忘记字节的性别 180 3.15 技巧29:不要将IP地址或端口号硬编入应用程序中 182 3.16 技巧30:理解已连接的UDP套接字 187 3.17 技巧31:记住,并不是所有程序都是用C编写的 190 3.18 技巧32:理解缓冲区长度带来的影响 195 第4章 工具和资源 199 4.1 技巧33:熟悉ping实用工具 199 4.2 技巧34:学习使用tcpdump或类似的工具 201 4.2.1 tcpdump是如何工作的 202 4.2.2 使用tcpdump 205 4.2.3 tcpdump的输出 206 4.2.4 小结 210 4.3 技巧35:学习使用traceroute 210 4.3.1 traceroute是如何工作的 212 4.3.2 Windows TRACERT 214 4.3.3 小结 215 4.4 技巧36:学习使用ttcp 215 4.5 技巧37:学习使用lsof 219 4.6 技巧38:学习使用netstat 221 4.6.1 活动套接字 221 4.6.2 接口 223 4.6.3 路由表 223 4.6.4 协议统计 225 4.6.5 Windows版的netstat 227 4.6.6 小结 227 4.7 技巧39:学习使用系统中的调用追踪工具 227 4.7.1 过早终止 227 4.7.2 ttcp性能问题 231 4.7.3 小结 232 4.8 技巧40:构建并使用捕获ICMP报文的工具 233 4.8.1 读取ICMP报文 233 4.8.2 打印ICMP报文 234 4.8.3 小结 239 4.9 技巧41:读Stevens的书 240 4.9.1 《TCP/IP详解》丛书 240 4.9.2 《UNIX网络编程》丛书 241 4.10 技巧42:阅读代码 242 4.11 技巧43:访问RFC编辑者的页面 243 4.12 技巧44:经常访问新闻组 244 附录A 各种UNIX代码 247 附录B 各种Windows代码 250 参考书目 253 索引 257 ======================
本书详细介绍了利用Visual C# 2005进行网络编程的方法和技巧。全书共分13章,主要内容包括网络编程原理、Visual C# 2005的套接字以及多线程的开发、基于各种不同协议的网络编程应用模块,并通过几个典型的实例介绍了Visual C# 2005网络编程的实际应用。 本书注重代码的通用性和工程实践性,书中提供的通用模块和典型实例稍加修改就可以为读者所用。   本书不仅适用于使用Visual C# 2005进行软件开发的广大软件开发人员,也适合高等院校师生学习和参考使用,特别对高校计算机专业的学生进行毕业设计具有非常好的指导价值,也可以作为广大计算机编程爱好者的自学参考书。 第1章 C#.NET网络编程概述  1.1 网络通信概述   1.1.1 网络通信模型概述   1.1.2 网络通信协议、接口和服务概述   1.1.3 TCP/IP网络架构概述   1.1.4 IP地址与端口  1.2 C#.NET网络编程相关类   1.2.1 IPAddress类   1.2.2 DNS类   1.2.3 IPHostEntry类   1.2.4 IPEndPoint类   1.2.5 Socket类  1.3 套接字概述   1.3.1 套接字的类型和常用属性   1.3.2 建立面向连接的套接字   1.3.3 建立面向无连接的套接字  1.4 使用套接字的简单示例   1.4.1 C/S与B/S架构通信模式概述   1.4.2 编写客户端代码   1.4.3 编写服务器端代码 .  1.4.4 无阻塞套接字  1.5 本章小结 第2章 C#.NET高级网络编程技术概述  2.1 线程与网络通信   2.1.1 基于线程的网络通信概述   2.1.2 在网络编程中使用多线程   2.1.3 线程基础   2.1.4 多线程在网络编程中的应用  2.2 网络通信的常见问题   2.2.1 让网络通信代码更强壮   2.2.2 数据缓冲区处理方法  2.3 TCP无保护消息边界   2.3.1 发送固定长度的消息   2.3.2 采用变长的消息   2.3.3 使用特殊标记处理消息  2.4 本章小结 第3章 开发基于TCP协议的应用程序  3.1 套接字与TCP协议   3.1.1 使用套接字传输数据   3.1.2 NetworkStream对象同数据发送与接收   3.1.3 TcpClient与TcpListener类   3.1.4 使用TCP/IP协议编写应用层的通信代码  3.2 开发异步的TCP应用编程   3.2.1 TCP的异步通信程   3.2.2 线程阻塞与异步中的同步问题  3.3 开发异步的TCP聊天程序   3.3.1 客户端界面设计   3.3.2 客户端业务逻辑设计   3.3.3 服务器端界面设计   3.3.4 服务器端业务逻辑设计   3.3.5 运行界面  3.4 本章小结 第4章 开发基于UDP的应用程序  4.1 UDP通信协议概述   4.1.1 UDP协议与TCP协议的差别   4.1.2 UDP协议的使用场合  4.2 在C#下UDP协议的相关类   4.2.1 IPAddress类   4.2.2 UdpClient类的构造函数   4.2.3 UdpClient类的常用方法与实例  4.3 UDP协议使用示例   4.3.1 UDP模块功能概述   4.3.2 设计通信程   4.3.3 开发服务器端程序   4.3.4 开发客户端程序   4.3.5 使用多线程开发UDP协议   4.3.6 使用校验保证信息完整性   4.3.7 效果演示  4.4 本章小结 第5章 开发基于SNMP协议的应用程序  5.1 SNMP协议概述   5.1.1 了解SNMP协议   5.1.2 SNMP的常用命令   5.1.3 设计SNMP包  5.2 SNMP协议使用示例   5.2.1 需求分析与设计   5.2.2 设计程序程   5.2.3 程序窗口界面设计   5.2.4 SNMP类编写   5.2.5 SNMP程序窗口类编写  5.3 运行效果演示  5.4 使用供货商提供的MIB库  5.5 本章小结 第6章 使用.NET发送邮件  6.1 邮件发送与接收协议概述   6.1.1 SMTP协议与邮件发送   6.1.2 POP3协议与邮件接收   6.1.3 .NET下支持SMTP和POP3的类  6.2 邮件发送与接收模块   6.2.1 需求分析与设计   6.2.2 设计邮件发送和接收的程   6.2.3 界面设计   6.2.4 编写主窗口的业务逻辑   6.2.5 编写发送邮件的业务逻辑   6.2.6 编写接收邮件的业务逻辑   6.2.7 使用多线程发送与接收邮件  6.3 运行效果演示  6.4 本章小结 第7章 FTP下载与文件传输  7.1 FTP协议概述   7.1.1 使用FTP协议下载文件的程   7.1.2 相关类库说明  7.2 FTP客户端设计   7.2.1 需求分析   7.2.2 界面设计   7.2.3 业务逻辑设计  7.3 FTP服务器端设计   7.3.1 需求分析   7.3.2 FTP响应码   7.3.3 业务逻辑设计  7.4 运行界面  7.5 本章小结 第8章 基于C#.NET的网络管理模块  8.1 ICMP协议概述   8.1.1 ping命令   8.1.2 tracert命令  8.2 ICMP包  8.3 编写网络管理模块   8.3.1 需求分析   8.3.2 界面设计   8.3.3 编写核心icmp类的业务逻辑   8.3.4 编写具有ping功能的业务逻辑   8.3.5 编写具有tracert功能的业务逻辑   8.3.6 编写findmask功能的业务逻辑   8.3.7 编写时间戳功能的业务逻辑  8.4 运行界面  8.5 本章小结 第9章 编写基于.NET的Web Service  9.1 Web Service概述   9.1.1 Web服务基本概念   9.1.2 Web服务的优势   9.1.3 Web服务的架构  9.2 需求分析与设计   9.2.1 需求分析   9.2.2 文件功能设计   9.2.3 数据库设计  9.3 编写Web Service服务系统   9.3.1 构建Web Service   9.3.2 编写Web服务代码   9.3.3 主页面与登录相关的WebService数据访问模块   9.3.4 发表主题相关的Web Service访问模块   9.3.5 投票相关的Web Service访问模块   9.3.6 管理相关的Web Service访问模块  9.4 主页面与登录模块   9.4.1 界面设计   9.4.2 编写业务逻辑  9.5 发表主题模块   9.5.1 界面设计   9.5.2 编写业务逻辑  9.6 投票模块   9.6.1 界面设计   9.6.2 编写业务逻辑  9.7 管理模块   9.7.1 界面设计   9.7.2 编写业务逻辑  9.8 本章小结 第10章 基于.NET的远程技术  10.1 远程技术概述   10.1.1 远程技术开发结构   10.1.2 远程技术使用  10.2 远程控制开发客户端的设计   10.2.1 界面设计与控件使用   10.2.2 客户端的代码设计  10.3 远程控制开发服务器端的设计   10.3.1 界面设计与控件使用   10.3.2 服务器端的代码设计  10.4 运行效果演示  10.5 本章小结 第11章 媒体在线播放  11.1 需求分析与设计   11.1.1 需求分析   11.1.2 模块设计   11.1.3 数据库设计  11.2 DirectShow接口   11.2.1 滤波图模型   11.2.2 如何使用DirectShow接口   11.2.3 媒体在线播放相关接口  11.3 媒体协议   11.3.1 实时传输协议(RTP)   11.3.2 实时传输控制协议(RTCP)   11.3.3 实时传输协议(RTSP)   11.3.4 媒体服务过程  11.4 建立.NET的窗体项目   11.4.1 主窗口界面设计   11.4.2 收藏夹数据库相关业务逻辑设计   11.4.3 媒体在线播放器业务逻辑设计  11.5 运行效果演示  11.6 本章小结 第12章 在线五子棋系统模块  12.1 需求分析与设计   12.1.1 需求分析   12.1.2 模块设计  12.2 五子棋规则类设计   12.2.1 胜负判定类   12.2.2 行棋规则类  12.3 基于TCP协议的通信类   12.4 网络配置模块   12.4.1 网络配置模块的界面设计   12.4.2 网络配置模块的代码设计  12.5 扫描主机模块   12.5.1 扫描主机模块的界面设计   12.5.2 扫描主机模块的代码设计  12.6 主界面模块   12.6.1 主界面模块的界面设计   12.6.2 主界面模块的代码设计  12.7 运行界面  12.8 本章小结 第13章 基于HTTP协议的下载工具  13.1 HTTP协议   13.1.1 HTTP下载理论   13.1.2 .NET的几个支持HTTP协议的类  13.2 异步机制   13.2.1 异步机制的原理   13.2.2 异步类  13.3 下载工具的设计   13.3.1 需求设计   13.3.2 模块设计   13.3.3 界面设计   13.3.4 业务逻辑设计  13.4 运行效果演示  13.5 本章小结 Microsoft Visual C# 2005是一种新的编程环境,它是为生成在.NET Framework上运行的多种应用程序而设计的。C#简单,功能强大,类型安全,而且是面向对象的。C#凭借它的许多创新实现了对应用程序的快速开发。. Visual Studio支持Visual C#,这是通过功能齐全的代码编辑器、项目模板、设计器、代码向导、功能强大且易于使用的调试器以及其他工具实现的。通过.NET Framework类库,可以访问多种操作系统服务和其他有用的精心设计的类,这些类可显著加快开发周期。 本书大量地使用了.NET Framework提供的类库中的函数来协同开发,通过使用这些已经被封装的类来协助开发确实提高了不少效率,为开发工作带来了诸多的便利。 本书共分13章,第1章介绍了利用Visual C# 2005提供的网络命名空间下的诸多API进行套接字的开发,并对网络编程的原理进行了详细的阐述,为后续的章节奠定了基础。 第2章介绍了具有多线程能力的网络应用程序,这使得用户开发的程序能够适应更加复杂的情况。 第3章~第8章是本书的重要部分,主要介绍基于各种不同协议的网络编程应用模块。第3章介绍了基于TCP协议的聊天程序;第4章介绍了基于UDP的通信程序;第5章介绍了使用SNMP协议的网络管理程序;第6章介绍了使用SMTP以及POP3协议的E-mail系统;第7章介绍了基于FTP的文件传输模块;第8章介绍了使用ICMP协议的网络探测程序。 第9章介绍了基于Web Service的电子公告板系统,并结合采用了SQL Server 2005数据库;第10章介绍了使用远程控制技术的应用程序;第11章则介绍了媒体在线播放系统。.. 第12章介绍了基于TCP通信协议的在线五子棋系统;第13章主要介绍了基于HTTP协议的下载工具,该工具具有多线程下载、断点续传的功能。 本书注重理论指导性和工程实践性,书中提供的各个网络应用程序只要稍加修改就可以为读者所用。本书不仅适用于使用Visual C# 2005进行软件开发的广大软件开发人员,也适合高等院校师生学习和参考使用,特别对高校计算机专业的学生进行毕业设计具有非常好的指导价值,也可以作为广大计算机编程爱好者的自学、参考用书。 本书主要由梅晓冬、颜烨青执笔,在编写本书程序的过程中,得到了陈璧元的大力支持,在此表示衷心的感谢。此外,还要感谢杨文军、程伟、袁远、刘武、彭澜、李通、李杰、卢茂琼、张燕生、胡燕生、邓湘成、卢下知、王周浩、邱岳、刘、代本、刘明星、孙靖华等人,他们在本书编写过程中给予了我鼓励和支持。 由于时间仓促,加之水平有限,书中不足之处在所难免,敬请读者批评指正。... 编者 2008年1月

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值