IO多路复用之select全面总结(必看篇)
<p><span><strong>1、基本概念</strong></span></p>
<p>
io多路复用是指内核一旦发现进程指定的一个或者多个io条件准备读取,它就通知该进程。io多路复用适用如下场合:</p>
<p>
(1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用i/o复用。</p>
<p>
(2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。</p>
<p>
(3)如果一个tcp服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到i/o复用。</p>
<p>
(4)如果一个服务器即要处理tcp,又要处理udp,一般要使用i/o复用。</p>
<p>
(5)如果一个服务器要处理多个服务或多个协议,一般要使用i/o复用。</p>
<p>
与多进程和多线程技术相比,i/o多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。</p>
<p>
<span><strong>2、select函数</strong></span></p>
<p>
该函数准许进程指示内核等待多个事件中的任何一个发送,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒。函数原型如下:</p>
<p>
<strong><span>#include <sys/select.h><br>
#include <sys/time.h></span></strong></p>
<p>
<strong><span>int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout)</span></strong></p>
<p>
返回值:就绪描述符的数目,超时返回0,出错返回-1</p>
<p>
<span><strong>函数参数介绍如下:</strong></span></p>
<p>
(1)第一个参数maxfdp1指定待测试的描述字个数,它的值是待测试的最大描述字加1(因此把该参数命名为maxfdp1),描述字0、1、2...maxfdp1-1均将被测试。</p>
<p>
因为文件描述符是从0开始的。</p>
<p>
(2)中间的三个参数readset、writeset和exceptset指定我们要让内核测试读、写和异常条件的描述字。如果对某一个的条件不感兴趣,就可以把它设为空指针。struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符,可通过以下四个宏进行设置:</p>
<p>
void fd_zero(fd_set *fdset); //清空集合</p>
<p>
void fd_set(int fd, fd_set *fdset); //将一个给定的文件描述符加入集合之中</p>
<p>
void fd_clr(int fd, fd_set *fdset); //将一个给定的文件描述符从集合中删除</p>
<p>
int fd_isset(int fd, fd_set *fdset); // 检查集合中指定的文件描述符是否可以读写</p>
<p>
(3)timeout告知内核等待所指定描述字中的任何一个就绪可花多少时间。其timeval结构用于指定这段时间的秒数和微秒数。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterxhtml" id="highlighter_148604">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="xhtml plain">struct timeval{</code>
</div>
<div class="line number2 index1 alt1">
</div>
<div class="line number3 index2 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">long tv_sec; //seconds</code>
</div>
<div class="line number4 index3 alt1">
</div>
<div class="line number5 index4 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">long tv_usec; //microseconds</code>
</div>
<div class="line number6 index5 alt1">
</div>
<div class="line number7 index6 alt2">
<code class="xhtml plain">};</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<span><strong>这个参数有三种可能:</strong></span></p>
<p>
(1)永远等待下去:仅在有一个描述字准备好i/o时才返回。为此,把该参数设置为空指针null。</p>
<p>
(2)等待一段固定时间:在有一个描述字准备好i/o时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。</p>
<p>
(3)根本不等待:检查描述字后立即返回,这称为轮询。为此,该参数必须指向一个timeval结构,而且其中的定时器值必须为0。</p>
<p>
<strong> 原理图:</strong></p>
<p>
<img title="IO多路复用之select全面总结(必看篇)" alt="IO多路复用之select全面总结(必看篇)" src="https://zhuji.jb51.net/uploads/img/202305/c9c72d0af148b1fe4e49a3130cbc4aef.jpg"></p>
<p>
<span><strong>3、测试程序</strong></span></p>
<p>
写一个tcp回射程序,程序的功能是:客户端向服务器发送信息,服务器接收并原样发送给客户端,客户端显示出接收到的信息。</p>
<p>
服务端程序如下:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterxhtml" id="highlighter_292694">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
<div class="line number24 index23 alt1">
24</div>
<div class="line number25 index24 alt2">
25</div>
<div class="line number26 index25 alt1">
26</div>
<div class="line number27 index26 alt2">
27</div>
<div class="line number28 index27 alt1">
28</div>
<div class="line number29 index28 alt2">
29</div>
<div class="line number30 index29 alt1">
30</div>
<div class="line number31 index30 alt2">
31</div>
<div class="line number32 index31 alt1">
32</div>
<div class="line number33 index32 alt2">
33</div>
<div class="line number34 index33 alt1">
34</div>
<div class="line number35 index34 alt2">
35</div>
<div class="line number36 index35 alt1">
36</div>
<div class="line number37 index36 alt2">
37</div>
<div class="line number38 index37 alt1">
38</div>
<div class="line number39 index38 alt2">
39</div>
<div class="line number40 index39 alt1">
40</div>
<div class="line number41 index40 alt2">
41</div>
<div class="line number42 index41 alt1">
42</div>
<div class="line number43 index42 alt2">
43</div>
<div class="line number44 index43 alt1">
44</div>
<div class="line number45 index44 alt2">
45</div>
<div class="line number46 index45 alt1">
46</div>
<div class="line number47 index46 alt2">
47</div>
<div class="line number48 index47 alt1">
48</div>
<div class="line number49 index48 alt2">
49</div>
<div class="line number50 index49 alt1">
50</div>
<div class="line number51 index50 alt2">
51</div>
<div class="line number52 index51 alt1">
52</div>
<div class="line number53 index52 alt2">
53</div>
<div class="line number54 index53 alt1">
54</div>
<div class="line number55 index54 alt2">
55</div>
<div class="line number56 index55 alt1">
56</div>
<div class="line number57 index56 alt2">
57</div>
<div class="line number58 index57 alt1">
58</div>
<div class="line number59 index58 alt2">
59</div>
<div class="line number60 index59 alt1">
60</div>
<div class="line number61 index60 alt2">
61</div>
<div class="line number62 index61 alt1">
62</div>
<div class="line number63 index62 alt2">
63</div>
<div class="line number64 index63 alt1">
64</div>
<div class="line number65 index64 alt2">
65</div>
<div class="line number66 index65 alt1">
66</div>
<div class="line number67 index66 alt2">
67</div>
<div class="line number68 index67 alt1">
68</div>
<div class="line number69 index68 alt2">
69</div>
<div class="line number70 index69 alt1">
70</div>
<div class="line number71 index70 alt2">
71</div>
<div class="line number72 index71 alt1">
72</div>
<div class="line number73 index72 alt2">
73</div>
<div class="line number74 index73 alt1">
74</div>
<div class="line number75 index74 alt2">
75</div>
<div class="line number76 index75 alt1">
76</div>
<div class="line number77 index76 alt2">
77</div>
<div class="line number78 index77 alt1">
78</div>
<div class="line number79 index78 alt2">
79</div>
<div class="line number80 index79 alt1">
80</div>
<div class="line number81 index80 alt2">
81</div>
<div class="line number82 index81 alt1">
82</div>
<div class="line number83 index82 alt2">
83</div>
<div class="line number84 index83 alt1">
84</div>
<div class="line number85 index84 alt2">
85</div>
<div class="line number86 index85 alt1">
86</div>
<div class="line number87 index86 alt2">
87</div>
<div class="line number88 index87 alt1">
88</div>
<div class="line number89 index88 alt2">
89</div>
<div class="line number90 index89 alt1">
90</div>
<div class="line number91 index90 alt2">
91</div>
<div class="line number92 index91 alt1">
92</div>
<div class="line number93 index92 alt2">
93</div>
<div class="line number94 index93 alt1">
94</div>
<div class="line number95 index94 alt2">
95</div>
<div class="line number96 index95 alt1">
96</div>
<div class="line number97 index96 alt2">
97</div>
<div class="line number98 index97 alt1">
98</div>
<div class="line number99 index98 alt2">
99</div>
<div class="line number100 index99 alt1">
100</div>
<div class="line number101 index100 alt2">
101</div>
<div class="line number102 index101 alt1">
102</div>
<div class="line number103 index102 alt2">
103</div>
<div class="line number104 index103 alt1">
104</div>
<div class="line number105 index104 alt2">
105</div>
<div class="line number106 index105 alt1">
106</div>
<div class="line number107 index106 alt2">
107</div>
<div class="line number108 index107 alt1">
108</div>
<div class="line number109 index108 alt2">
109</div>
<div class="line number110 index109 alt1">
110</div>
<div class="line number111 index110 alt2">
111</div>
<div class="line number112 index111 alt1">
112</div>
<div class="line number113 index112 alt2">
113</div>
<div class="line number114 index113 alt1">
114</div>
<div class="line number115 index114 alt2">
115</div>
<div class="line number116 index115 alt1">
116</div>
<div class="line number117 index116 alt2">
117</div>
<div class="line number118 index117 alt1">
118</div>
<div class="line number119 index118 alt2">
119</div>
<div class="line number120 index119 alt1">
120</div>
<div class="line number121 index120 alt2">
121</div>
<div class="line number122 index121 alt1">
122</div>
<div class="line number123 index122 alt2">
123</div>
<div class="line number124 index123 alt1">
124</div>
<div class="line number125 index124 alt2">
125</div>
<div class="line number126 index125 alt1">
126</div>
<div class="line number127 index126 alt2">
127</div>
<div class="line number128 index127 alt1">
128</div>
<div class="line number129 index128 alt2">
129</div>
<div class="line number130 index129 alt1">
130</div>
<div class="line number131 index130 alt2">
131</div>
<div class="line number132 index131 alt1">
132</div>
<div class="line number133 index132 alt2">
133</div>
<div class="line number134 index133 alt1">
134</div>
<div class="line number135 index134 alt2">
135</div>
<div class="line number136 index135 alt1">
136</div>
<div class="line number137 index136 alt2">
137</div>
<div class="line number138 index137 alt1">
138</div>
<div class="line number139 index138 alt2">
139</div>
<div class="line number140 index139 alt1">
140</div>
<div class="line number141 index140 alt2">
141</div>
<div class="line number142 index141 alt1">
142</div>
<div class="line number143 index142 alt2">
143</div>
<div class="line number144 index143 alt1">
144</div>
<div class="line number145 index144 alt2">
145</div>
<div class="line number146 index145 alt1">
146</div>
<div class="line number147 index146 alt2">
147</div>
<div class="line number148 index147 alt1">
148</div>
<div class="line number149 index148 alt2">
149</div>
<div class="line number150 index149 alt1">
150</div>
<div class="line number151 index150 alt2">
151</div>
<div class="line number152 index151 alt1">
152</div>
<div class="line number153 index152 alt2">
153</div>
<div class="line number154 index153 alt1">
154</div>
<div class="line number155 index154 alt2">
155</div>
<div class="line number156 index155 alt1">
156</div>
<div class="line number157 index156 alt2">
157</div>
<div class="line number158 index157 alt1">
158</div>
<div class="line number159 index158 alt2">
159</div>
<div class="line number160 index159 alt1">
160</div>
<div class="line number161 index160 alt2">
161</div>
<div class="line number162 index161 alt1">
162</div>
<div class="line number163 index162 alt2">
163</div>
<div class="line number164 index163 alt1">
164</div>
<div class="line number165 index164 alt2">
165</div>
<div class="line number166 index165 alt1">
166</div>
<div class="line number167 index166 alt2">
167</div>
<div class="line number168 index167 alt1">
168</div>
<div class="line number169 index168 alt2">
169</div>
<div class="line number170 index169 alt1">
170</div>
<div class="line number171 index170 alt2">
171</div>
<div class="line number172 index171 alt1">
172</div>
<div class="line number173 index172 alt2">
173</div>
<div class="line number174 index173 alt1">
174</div>
<div class="line number175 index174 alt2">
175</div>
<div class="line number176 index175 alt1">
176</div>
<div class="line number177 index176 alt2">
177</div>
<div class="line number178 index177 alt1">
178</div>
<div class="line number179 index178 alt2">
179</div>
<div class="line number180 index179 alt1">
180</div>
<div class="line number181 index180 alt2">
181</div>
<div class="line number182 index181 alt1">
182</div>
<div class="line number183 index182 alt2">
183</div>
<div class="line number184 index183 alt1">
184</div>
<div class="line number185 index184 alt2">
185</div>
<div class="line number186 index185 alt1">
186</div>
<div class="line number187 index186 alt2">
187</div>
<div class="line number188 index187 alt1">
188</div>
<div class="line number189 index188 alt2">
189</div>
<div class="line number190 index189 alt1">
190</div>
<div class="line number191 index190 alt2">
191</div>
<div class="line number192 index191 alt1">
192</div>
<div class="line number193 index192 alt2">
193</div>
<div class="line number194 index193 alt1">
194</div>
<div class="line number195 index194 alt2">
195</div>
<div class="line number196 index195 alt1">
196</div>
<div class="line number197 index196 alt2">
197</div>
<div class="line number198 index197 alt1">
198</div>
<div class="line number199 index198 alt2">
199</div>
<div class="line number200 index199 alt1">
200</div>
<div class="line number201 index200 alt2">
201</div>
<div class="line number202 index201 alt1">
202</div>
<div class="line number203 index202 alt2">
203</div>
<div class="line number204 index203 alt1">
204</div>
<div class="line number205 index204 alt2">
205</div>
<div class="line number206 index205 alt1">
206</div>
<div class="line number207 index206 alt2">
207</div>
<div class="line number208 index207 alt1">
208</div>
<div class="line number209 index208 alt2">
209</div>
<div class="line number210 index209 alt1">
210</div>
<div class="line number211 index210 alt2">
211</div>
<div class="line number212 index211 alt1">
212</div>
<div class="line number213 index212 alt2">
213</div>
<div class="line number214 index213 alt1">
214</div>
<div class="line number215 index214 alt2">
215</div>
<div class="line number216 index215 alt1">
216</div>
<div class="line number217 index216 alt2">
217</div>
<div class="line number218 index217 alt1">
218</div>
<div class="line number219 index218 alt2">
219</div>
<div class="line number220 index219 alt1">
220</div>
<div class="line number221 index220 alt2">
221</div>
<div class="line number222 index221 alt1">
222</div>
<div class="line number223 index222 alt2">
223</div>
<div class="line number224 index223 alt1">
224</div>
<div class="line number225 index224 alt2">
225</div>
<div class="line number226 index225 alt1">
226</div>
<div class="line number227 index226 alt2">
227</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">stdio.h</code><code class="xhtml plain">></code>
</div>
<div class="line number2 index1 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">stdlib.h</code><code class="xhtml plain">></code>
</div>
<div class="line number3 index2 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">string.h</code><code class="xhtml plain">></code>
</div>
<div class="line number4 index3 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">errno.h</code><code class="xhtml plain">></code>
</div>
<div class="line number5 index4 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">netinet</code><code class="xhtml plain">/in.h></code>
</div>
<div class="line number6 index5 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/socket.h></code>
</div>
<div class="line number7 index6 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/select.h></code>
</div>
<div class="line number8 index7 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/types.h></code>
</div>
<div class="line number9 index8 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">netinet</code><code class="xhtml plain">/in.h></code>
</div>
<div class="line number10 index9 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">arpa</code><code class="xhtml plain">/inet.h></code>
</div>
<div class="line number11 index10 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">unistd.h</code><code class="xhtml plain">></code>
</div>
<div class="line number12 index11 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">assert.h</code><code class="xhtml plain">></code>
</div>
<div class="line number13 index12 alt2">
</div>
<div class="line number14 index13 alt1">
<code class="xhtml plain">#define ipaddr "127.0.0.1"</code>
</div>
<div class="line number15 index14 alt2">
<code class="xhtml plain">#define port 8787</code>
</div>
<div class="line number16 index15 alt1">
<code class="xhtml plain">#define maxline 1024</code>
</div>
<div class="line number17 index16 alt2">
<code class="xhtml plain">#define listenq 5</code>
</div>
<div class="line number18 index17 alt1">
<code class="xhtml plain">#define size 10</code>
</div>
<div class="line number19 index18 alt2">
</div>
<div class="line number20 index19 alt1">
<code class="xhtml plain">typedef struct server_context_st</code>
</div>
<div class="line number21 index20 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number22 index21 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">int cli_cnt; /*客户端个数*/</code>
</div>
<div class="line number23 index22 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int clifds; /*客户端的个数*/</code>
</div>
<div class="line number24 index23 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">fd_set allfds; /*句柄集合*/</code>
</div>
<div class="line number25 index24 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int maxfd; /*句柄最大值*/</code>
</div>
<div class="line number26 index25 alt1">
<code class="xhtml plain">} server_context_st;</code>
</div>
<div class="line number27 index26 alt2">
<code class="xhtml plain">static server_context_st *s_srv_ctx = null;</code>
</div>
<div class="line number28 index27 alt1">
<code class="xhtml plain">/*===========================================================================</code>
</div>
<div class="line number29 index28 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">* ==========================================================================*/</code>
</div>
<div class="line number30 index29 alt1">
<code class="xhtml plain">static int create_server_proc(const char* ip,int port)</code>
</div>
<div class="line number31 index30 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number32 index31 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">int fd;</code>
</div>
<div class="line number33 index32 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">struct sockaddr_in servaddr;</code>
</div>
<div class="line number34 index33 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">fd = socket(af_inet, sock_stream,0);</code>
</div>
<div class="line number35 index34 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (fd == -1) {</code>
</div>
<div class="line number36 index35 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">fprintf(stderr, "create socket fail,erron:%d,reason:%s\n",</code>
</div>
<div class="line number37 index36 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">errno, strerror(errno));</code>
</div>
<div class="line number38 index37 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number39 index38 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number40 index39 alt1">
</div>
<div class="line number41 index40 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*一个端口释放后会等待两分钟之后才能再被使用,so_reuseaddr是让端口释放后立即就可以被再次使用。*/</code>
</div>
<div class="line number42 index41 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">int reuse = 1;</code>
</div>
<div class="line number43 index42 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (setsockopt(fd, sol_socket, so_reuseaddr, &reuse, sizeof(reuse)) == -1) {</code>
</div>
<div class="line number44 index43 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number45 index44 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number46 index45 alt1">
</div>
<div class="line number47 index46 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">bzero(&servaddr,sizeof(servaddr));</code>
</div>
<div class="line number48 index47 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">servaddr.sin_family = af_inet;</code>
</div>
<div class="line number49 index48 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">inet_pton(af_inet,ip,&servaddr.sin_addr);</code>
</div>
<div class="line number50 index49 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">servaddr.sin_port = htons(port);</code>
</div>
<div class="line number51 index50 alt2">
</div>
<div class="line number52 index51 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (bind(fd,(struct sockaddr*)&servaddr,sizeof(servaddr)) == -1) {</code>
</div>
<div class="line number53 index52 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">perror("bind error: ");</code>
</div>
<div class="line number54 index53 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number55 index54 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number56 index55 alt1">
</div>
<div class="line number57 index56 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">listen(fd,listenq);</code>
</div>
<div class="line number58 index57 alt1">
</div>
<div class="line number59 index58 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">return fd;</code>
</div>
<div class="line number60 index59 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number61 index60 alt2">
</div>
<div class="line number62 index61 alt1">
<code class="xhtml plain">static int accept_client_proc(int srvfd)</code>
</div>
<div class="line number63 index62 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number64 index63 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">struct sockaddr_in cliaddr;</code>
</div>
<div class="line number65 index64 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">socklen_t cliaddrlen;</code>
</div>
<div class="line number66 index65 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">cliaddrlen = sizeof(cliaddr);</code>
</div>
<div class="line number67 index66 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int clifd = -1;</code>
</div>
<div class="line number68 index67 alt1">
</div>
<div class="line number69 index68 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">printf("accpet clint proc is called.\n");</code>
</div>
<div class="line number70 index69 alt1">
</div>
<div class="line number71 index70 alt2">
<code class="xhtml plain">accept:</code>
</div>
<div class="line number72 index71 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">clifd = accept(srvfd,(struct sockaddr*)&cliaddr,&cliaddrlen);</code>
</div>
<div class="line number73 index72 alt2">
</div>
<div class="line number74 index73 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (clifd == -1) {</code>
</div>
<div class="line number75 index74 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (errno == eintr) {</code>
</div>
<div class="line number76 index75 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">goto accept;</code>
</div>
<div class="line number77 index76 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">} else {</code>
</div>
<div class="line number78 index77 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">fprintf(stderr, "accept fail,error:%s\n", strerror(errno));</code>
</div>
<div class="line number79 index78 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number80 index79 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number81 index80 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number82 index81 alt1">
</div>
<div class="line number83 index82 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fprintf(stdout, "accept a new client: %s:%d\n",</code>
</div>
<div class="line number84 index83 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">inet_ntoa(cliaddr.sin_addr),cliaddr.sin_port);</code>
</div>
<div class="line number85 index84 alt2">
</div>
<div class="line number86 index85 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">//将新的连接描述符添加到数组中</code>
</div>
<div class="line number87 index86 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int i = 0;</code>
</div>
<div class="line number88 index87 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">for (i = 0; i < </code><code class="xhtml keyword">size</code><code class="xhtml plain">; i++) {</code>
</div>
<div class="line number89 index88 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (s_srv_ctx->clifds < </code><code class="xhtml keyword">0</code><code class="xhtml plain">) {</code>
</div>
<div class="line number90 index89 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx->clifds = clifd;</code>
</div>
<div class="line number91 index90 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx->cli_cnt++;</code>
</div>
<div class="line number92 index91 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">break;</code>
</div>
<div class="line number93 index92 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number94 index93 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number95 index94 alt2">
</div>
<div class="line number96 index95 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (i == size) {</code>
</div>
<div class="line number97 index96 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fprintf(stderr,"too many clients.\n");</code>
</div>
<div class="line number98 index97 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number99 index98 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number100 index99 alt1">
<code class="xhtml plain">101 }</code>
</div>
<div class="line number101 index100 alt2">
</div>
<div class="line number102 index101 alt1">
<code class="xhtml plain">static int handle_client_msg(int fd, char *buf) </code>
</div>
<div class="line number103 index102 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number104 index103 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">assert(buf);</code>
</div>
<div class="line number105 index104 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">printf("recv buf is :%s\n", buf);</code>
</div>
<div class="line number106 index105 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">write(fd, buf, strlen(buf) +1);</code>
</div>
<div class="line number107 index106 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">return 0;</code>
</div>
<div class="line number108 index107 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number109 index108 alt2">
</div>
<div class="line number110 index109 alt1">
<code class="xhtml plain">static void recv_client_msg(fd_set *readfds)</code>
</div>
<div class="line number111 index110 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number112 index111 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">int i = 0, n = 0;</code>
</div>
<div class="line number113 index112 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int clifd;</code>
</div>
<div class="line number114 index113 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">char buf = {0};</code>
</div>
<div class="line number115 index114 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">for (i = 0;i <= s_srv_ctx->cli_cnt;i++) {</code>
</div>
<div class="line number116 index115 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">clifd = s_srv_ctx->clifds;</code>
</div>
<div class="line number117 index116 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (clifd < </code><code class="xhtml keyword">0</code><code class="xhtml plain">) {</code>
</div>
<div class="line number118 index117 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">continue;</code>
</div>
<div class="line number119 index118 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number120 index119 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*判断客户端套接字是否有数据*/</code>
</div>
<div class="line number121 index120 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (fd_isset(clifd, readfds)) {</code>
</div>
<div class="line number122 index121 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">//接收客户端发送的信息</code>
</div>
<div class="line number123 index122 alt2">
<code class="xhtml spaces"> </code><code class="xhtml color1">n</code> <code class="xhtml plain">= </code><code class="xhtml string">read</code><code class="xhtml plain">(clifd, buf, maxline);</code>
</div>
<div class="line number124 index123 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (n <= 0) {</code>
</div>
<div class="line number125 index124 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*n==0表示读取完成,客户都关闭套接字*/</code>
</div>
<div class="line number126 index125 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">fd_clr(clifd, &s_srv_ctx->allfds);</code>
</div>
<div class="line number127 index126 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">close(clifd);</code>
</div>
<div class="line number128 index127 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx->clifds = -1;</code>
</div>
<div class="line number129 index128 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">continue;</code>
</div>
<div class="line number130 index129 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number131 index130 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">handle_client_msg(clifd, buf);</code>
</div>
<div class="line number132 index131 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number133 index132 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number134 index133 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number135 index134 alt2">
<code class="xhtml plain">static void handle_client_proc(int srvfd)</code>
</div>
<div class="line number136 index135 alt1">
<code class="xhtml plain">{</code>
</div>
<div class="line number137 index136 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int clifd = -1;</code>
</div>
<div class="line number138 index137 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">int retval = 0;</code>
</div>
<div class="line number139 index138 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fd_set *readfds = &s_srv_ctx->allfds;</code>
</div>
<div class="line number140 index139 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">struct timeval tv;</code>
</div>
<div class="line number141 index140 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int i = 0;</code>
</div>
<div class="line number142 index141 alt1">
</div>
<div class="line number143 index142 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">while (1) {</code>
</div>
<div class="line number144 index143 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*每次调用select前都要重新设置文件描述符和时间,因为事件发生后,文件描述符和时间都被内核修改啦*/</code>
</div>
<div class="line number145 index144 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fd_zero(readfds);</code>
</div>
<div class="line number146 index145 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*添加监听套接字*/</code>
</div>
<div class="line number147 index146 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fd_set(srvfd, readfds);</code>
</div>
<div class="line number148 index147 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx->maxfd = srvfd;</code>
</div>
<div class="line number149 index148 alt2">
</div>
<div class="line number150 index149 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">tv.tv_sec = 30;</code>
</div>
<div class="line number151 index150 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">tv.tv_usec = 0;</code>
</div>
<div class="line number152 index151 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*添加客户端套接字*/</code>
</div>
<div class="line number153 index152 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">for (i = 0; i < </code><code class="xhtml keyword">s_srv_ctx-</code><code class="xhtml plain">>cli_cnt; i++) {</code>
</div>
<div class="line number154 index153 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">clifd = s_srv_ctx->clifds;</code>
</div>
<div class="line number155 index154 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*去除无效的客户端句柄*/</code>
</div>
<div class="line number156 index155 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (clifd != -1) {</code>
</div>
<div class="line number157 index156 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fd_set(clifd, readfds);</code>
</div>
<div class="line number158 index157 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number159 index158 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx->maxfd = (clifd > s_srv_ctx->maxfd ? clifd : s_srv_ctx->maxfd);</code>
</div>
<div class="line number160 index159 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number161 index160 alt2">
</div>
<div class="line number162 index161 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*开始轮询接收处理服务端和客户端套接字*/</code>
</div>
<div class="line number163 index162 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">retval = select(s_srv_ctx->maxfd + 1, readfds, null, null, &tv);</code>
</div>
<div class="line number164 index163 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (retval == -1) {</code>
</div>
<div class="line number165 index164 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fprintf(stderr, "select error:%s.\n", strerror(errno));</code>
</div>
<div class="line number166 index165 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return;</code>
</div>
<div class="line number167 index166 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number168 index167 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (retval == 0) {</code>
</div>
<div class="line number169 index168 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fprintf(stdout, "select is timeout.\n");</code>
</div>
<div class="line number170 index169 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">continue;</code>
</div>
<div class="line number171 index170 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number172 index171 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (fd_isset(srvfd, readfds)) {</code>
</div>
<div class="line number173 index172 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*监听客户端请求*/</code>
</div>
<div class="line number174 index173 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">accept_client_proc(srvfd);</code>
</div>
<div class="line number175 index174 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">} else {</code>
</div>
<div class="line number176 index175 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*接受处理客户端消息*/</code>
</div>
<div class="line number177 index176 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">recv_client_msg(readfds);</code>
</div>
<div class="line number178 index177 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number179 index178 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number180 index179 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number181 index180 alt2">
</div>
<div class="line number182 index181 alt1">
<code class="xhtml plain">static void server_uninit()</code>
</div>
<div class="line number183 index182 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number184 index183 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (s_srv_ctx) {</code>
</div>
<div class="line number185 index184 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">free(s_srv_ctx);</code>
</div>
<div class="line number186 index185 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx = null;</code>
</div>
<div class="line number187 index186 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number188 index187 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number189 index188 alt2">
</div>
<div class="line number190 index189 alt1">
<code class="xhtml plain">static int server_init()</code>
</div>
<div class="line number191 index190 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number192 index191 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx = (server_context_st *)malloc(sizeof(server_context_st));</code>
</div>
<div class="line number193 index192 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (s_srv_ctx == null) {</code>
</div>
<div class="line number194 index193 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number195 index194 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number196 index195 alt1">
</div>
<div class="line number197 index196 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">memset(s_srv_ctx, 0, sizeof(server_context_st));</code>
</div>
<div class="line number198 index197 alt1">
</div>
<div class="line number199 index198 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int i = 0;</code>
</div>
<div class="line number200 index199 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">for (;i < </code><code class="xhtml keyword">size</code><code class="xhtml plain">; i++) {</code>
</div>
<div class="line number201 index200 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">s_srv_ctx->clifds = -1;</code>
</div>
<div class="line number202 index201 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number203 index202 alt2">
</div>
<div class="line number204 index203 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return 0;</code>
</div>
<div class="line number205 index204 alt2">
<code class="xhtml plain">}</code>
</div>
<div class="line number206 index205 alt1">
</div>
<div class="line number207 index206 alt2">
<code class="xhtml plain">int main(int argc,char *argv[])</code>
</div>
<div class="line number208 index207 alt1">
<code class="xhtml plain">{</code>
</div>
<div class="line number209 index208 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">int srvfd;</code>
</div>
<div class="line number210 index209 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*初始化服务端context*/</code>
</div>
<div class="line number211 index210 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (server_init() < 0) {</code>
</div>
<div class="line number212 index211 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number213 index212 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number214 index213 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*创建服务,开始监听客户端请求*/</code>
</div>
<div class="line number215 index214 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">srvfd = create_server_proc(ipaddr, port);</code>
</div>
<div class="line number216 index215 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">if (srvfd < 0) {</code>
</div>
<div class="line number217 index216 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">fprintf(stderr, "socket create or bind fail.\n");</code>
</div>
<div class="line number218 index217 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">goto err;</code>
</div>
<div class="line number219 index218 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
<div class="line number220 index219 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">/*开始接收并处理客户端请求*/</code>
</div>
<div class="line number221 index220 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">handle_client_proc(srvfd);</code>
</div>
<div class="line number222 index221 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">server_uninit();</code>
</div>
<div class="line number223 index222 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">return 0;</code>
</div>
<div class="line number224 index223 alt1">
<code class="xhtml plain">err:</code>
</div>
<div class="line number225 index224 alt2">
<code class="xhtml spaces"> </code><code class="xhtml plain">server_uninit();</code>
</div>
<div class="line number226 index225 alt1">
<code class="xhtml spaces"> </code><code class="xhtml plain">return -1;</code>
</div>
<div class="line number227 index226 alt2">
<code class="xhtml plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
客户端程序如下:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterxhtml" id="highlighter_274791">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
<div class="line number24 index23 alt1">
24</div>
<div class="line number25 index24 alt2">
25</div>
<div class="line number26 index25 alt1">
26</div>
<div class="line number27 index26 alt2">
27</div>
<div class="line number28 index27 alt1">
28</div>
<div class="line number29 index28 alt2">
29</div>
<div class="line number30 index29 alt1">
30</div>
<div class="line number31 index30 alt2">
31</div>
<div class="line number32 index31 alt1">
32</div>
<div class="line number33 index32 alt2">
33</div>
<div class="line number34 index33 alt1">
34</div>
<div class="line number35 index34 alt2">
35</div>
<div class="line number36 index35 alt1">
36</div>
<div class="line number37 index36 alt2">
37</div>
<div class="line number38 index37 alt1">
38</div>
<div class="line number39 index38 alt2">
39</div>
<div class="line number40 index39 alt1">
40</div>
<div class="line number41 index40 alt2">
41</div>
<div class="line number42 index41 alt1">
42</div>
<div class="line number43 index42 alt2">
43</div>
<div class="line number44 index43 alt1">
44</div>
<div class="line number45 index44 alt2">
45</div>
<div class="line number46 index45 alt1">
46</div>
<div class="line number47 index46 alt2">
47</div>
<div class="line number48 index47 alt1">
48</div>
<div class="line number49 index48 alt2">
49</div>
<div class="line number50 index49 alt1">
50</div>
<div class="line number51 index50 alt2">
51</div>
<div class="line number52 index51 alt1">
52</div>
<div class="line number53 index52 alt2">
53</div>
<div class="line number54 index53 alt1">
54</div>
<div class="line number55 index54 alt2">
55</div>
<div class="line number56 index55 alt1">
56</div>
<div class="line number57 index56 alt2">
57</div>
<div class="line number58 index57 alt1">
58</div>
<div class="line number59 index58 alt2">
59</div>
<div class="line number60 index59 alt1">
60</div>
<div class="line number61 index60 alt2">
61</div>
<div class="line number62 index61 alt1">
62</div>
<div class="line number63 index62 alt2">
63</div>
<div class="line number64 index63 alt1">
64</div>
<div class="line number65 index64 alt2">
65</div>
<div class="line number66 index65 alt1">
66</div>
<div class="line number67 index66 alt2">
67</div>
<div class="line number68 index67 alt1">
68</div>
<div class="line number69 index68 alt2">
69</div>
<div class="line number70 index69 alt1">
70</div>
<div class="line number71 index70 alt2">
71</div>
<div class="line number72 index71 alt1">
72</div>
<div class="line number73 index72 alt2">
73</div>
<div class="line number74 index73 alt1">
74</div>
<div class="line number75 index74 alt2">
75</div>
<div class="line number76 index75 alt1">
76</div>
<div class="line number77 index76 alt2">
77</div>
<div class="line number78 index77 alt1">
78</div>
<div class="line number79 index78 alt2">
79</div>
<div class="line number80 index79 alt1">
80</div>
<div class="line number81 index80 alt2">
81</div>
<div class="line number82 index81 alt1">
82</div>
<div class="line number83 index82 alt2">
83</div>
<div class="line number84 index83 alt1">
84</div>
<div class="line number85 index84 alt2">
85</div>
<div class="line number86 index85 alt1">
86</div>
<div class="line number87 index86 alt2">
87</div>
<div class="line number88 index87 alt1">
88</div>
<div class="line number89 index88 alt2">
89</div>
<div class="line number90 index89 alt1">
90</div>
<div class="line number91 index90 alt2">
91</div>
<div class="line number92 index91 alt1">
92</div>
<div class="line number93 index92 alt2">
93</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">netinet</code><code class="xhtml plain">/in.h></code>
</div>
<div class="line number2 index1 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/socket.h></code>
</div>
<div class="line number3 index2 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">stdio.h</code><code class="xhtml plain">></code>
</div>
<div class="line number4 index3 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">string.h</code><code class="xhtml plain">></code>
</div>
<div class="line number5 index4 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">stdlib.h</code><code class="xhtml plain">></code>
</div>
<div class="line number6 index5 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/select.h></code>
</div>
<div class="line number7 index6 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">time.h</code><code class="xhtml plain">></code>
</div>
<div class="line number8 index7 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">unistd.h</code><code class="xhtml plain">></code>
</div>
<div class="line number9 index8 alt2">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/types.h></code>
</div>
<div class="line number10 index9 alt1">
<code class="xhtml plain">#include <</code><code class="xhtml keyword">errno.h</code><code class="xhtml plain">></code>
</div>
<div class="line number11 index10 alt2">
</div>
<div class="line number12 index11 alt1">
<code class="xhtml plain">#define maxline 1024</code>
</div>
<div class="line number13 index12 alt2">
<code class="xhtml plain">#define ipaddress "127.0.0.1"</code>
</div>
<div class="line number14 index13 alt1">
<code class="xhtml plain">#define serv_port 8787</code>
</div>
<div class="line number15 index14 alt2">
</div>
<div class="line number16 index15 alt1">
<code class="xhtml plain">#define max(a,b) (a > b) ? a : b</code>
</div>
<div class="line number17 index16 alt2">
</div>
<div class="line number18 index17 alt1">
<code class="xhtml plain">static void handle_recv_msg(int sockfd, char *buf) </code>
</div>
<div class="line number19 index18 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number20 index19 alt1">
<code class="xhtml plain">printf("client recv msg is:%s\n", buf);</code>
</div>
<div class="line number21 index20 alt2">
<code class="xhtml plain">sleep(5);</code>
</div>
<div class="line number22 index21 alt1">
<code class="xhtml plain">write(sockfd, buf, strlen(buf) +1);</code>
</div>
<div class="line number23 index22 alt2">
<code class="xhtml plain">}</code>
</div>
<div class="line number24 index23 alt1">
</div>
<div class="line number25 index24 alt2">
<code class="xhtml plain">static void handle_connection(int sockfd)</code>
</div>
<div class="line number26 index25 alt1">
<code class="xhtml plain">{</code>
</div>
<div class="line number27 index26 alt2">
<code class="xhtml plain">char sendline,recvline;</code>
</div>
<div class="line number28 index27 alt1">
<code class="xhtml plain">int maxfdp,stdineof;</code>
</div>
<div class="line number29 index28 alt2">
<code class="xhtml plain">fd_set readfds;</code>
</div>
<div class="line number30 index29 alt1">
<code class="xhtml plain">int n;</code>
</div>
<div class="line number31 index30 alt2">
<code class="xhtml plain">struct timeval tv;</code>
</div>
<div class="line number32 index31 alt1">
<code class="xhtml plain">int retval = 0;</code>
</div>
<div class="line number33 index32 alt2">
</div>
<div class="line number34 index33 alt1">
<code class="xhtml plain">while (1) {</code>
</div>
<div class="line number35 index34 alt2">
</div>
<div class="line number36 index35 alt1">
<code class="xhtml plain">fd_zero(&readfds);</code>
</div>
<div class="line number37 index36 alt2">
<code class="xhtml plain">fd_set(sockfd,&readfds);</code>
</div>
<div class="line number38 index37 alt1">
<code class="xhtml plain">maxfdp = sockfd;</code>
</div>
<div class="line number39 index38 alt2">
</div>
<div class="line number40 index39 alt1">
<code class="xhtml plain">tv.tv_sec = 5;</code>
</div>
<div class="line number41 index40 alt2">
<code class="xhtml plain">tv.tv_usec = 0;</code>
</div>
<div class="line number42 index41 alt1">
</div>
<div class="line number43 index42 alt2">
<code class="xhtml plain">retval = select(maxfdp+1,&readfds,null,null,&tv);</code>
</div>
<div class="line number44 index43 alt1">
</div>
<div class="line number45 index44 alt2">
<code class="xhtml plain">if (retval == -1) {</code>
</div>
<div class="line number46 index45 alt1">
<code class="xhtml plain">return ;</code>
</div>
<div class="line number47 index46 alt2">
<code class="xhtml plain">}</code>
</div>
<div class="line number48 index47 alt1">
</div>
<div class="line number49 index48 alt2">
<code class="xhtml plain">if (retval == 0) {</code>
</div>
<div class="line number50 index49 alt1">
<code class="xhtml plain">printf("client timeout.\n");</code>
</div>
<div class="line number51 index50 alt2">
<code class="xhtml plain">continue;</code>
</div>
<div class="line number52 index51 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number53 index52 alt2">
</div>
<div class="line number54 index53 alt1">
<code class="xhtml plain">if (fd_isset(sockfd, &readfds)) {</code>
</div>
<div class="line number55 index54 alt2">
<code class="xhtml plain">n = read(sockfd,recvline,maxline);</code>
</div>
<div class="line number56 index55 alt1">
<code class="xhtml plain">if (n <= 0) {</code>
</div>
<div class="line number57 index56 alt2">
<code class="xhtml plain">fprintf(stderr,"client: server is closed.\n");</code>
</div>
<div class="line number58 index57 alt1">
<code class="xhtml plain">close(sockfd);</code>
</div>
<div class="line number59 index58 alt2">
<code class="xhtml plain">fd_clr(sockfd,&readfds);</code>
</div>
<div class="line number60 index59 alt1">
<code class="xhtml plain">return;</code>
</div>
<div class="line number61 index60 alt2">
<code class="xhtml plain">}</code>
</div>
<div class="line number62 index61 alt1">
</div>
<div class="line number63 index62 alt2">
<code class="xhtml plain">handle_recv_msg(sockfd, recvline);</code>
</div>
<div class="line number64 index63 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number65 index64 alt2">
<code class="xhtml plain">}</code>
</div>
<div class="line number66 index65 alt1">
<code class="xhtml plain">}</code>
</div>
<div class="line number67 index66 alt2">
</div>
<div class="line number68 index67 alt1">
<code class="xhtml plain">int main(int argc,char *argv[])</code>
</div>
<div class="line number69 index68 alt2">
<code class="xhtml plain">{</code>
</div>
<div class="line number70 index69 alt1">
<code class="xhtml plain">int sockfd;</code>
</div>
<div class="line number71 index70 alt2">
<code class="xhtml plain">struct sockaddr_in servaddr;</code>
</div>
<div class="line number72 index71 alt1">
</div>
<div class="line number73 index72 alt2">
<code class="xhtml plain">sockfd = socket(af_inet,sock_stream,0);</code>
</div>
<div class="line number74 index73 alt1">
</div>
<div class="line number75 index74 alt2">
<code class="xhtml plain">bzero(&servaddr,sizeof(servaddr));</code>
</div>
<div class="line number76 index75 alt1">
<code class="xhtml plain">servaddr.sin_family = af_inet;</code>
</div>
<div class="line number77 index76 alt2">
<code class="xhtml plain">servaddr.sin_port = htons(serv_port);</code>
</div>
<div class="line number78 index77 alt1">
<code class="xhtml plain">inet_pton(af_inet,ipaddress,&servaddr.sin_addr);</code>
</div>
<div class="line number79 index78 alt2">
</div>
<div class="line number80 index79 alt1">
<code class="xhtml plain">int retval = 0;</code>
</div>
<div class="line number81 index80 alt2">
<code class="xhtml plain">retval = connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));</code>
</div>
<div class="line number82 index81 alt1">
<code class="xhtml plain">if (retval < 0) {</code>
</div>
<div class="line number83 index82 alt2">
<code class="xhtml plain">fprintf(stderr, "connect fail,error:%s\n", strerror(errno));</code>
</div>
<div class="line number84 index83 alt1">
<code class="xhtml plain">return -1;</code>
</div>
<div class="line number85 index84 alt2">
<code class="xhtml plain">}</code>
</div>
<div class="line number86 index85 alt1">
</div>
<div class="line number87 index86 alt2">
<code class="xhtml plain">printf("client send to server .\n");</code>
</div>
<div class="line number88 index87 alt1">
<code class="xhtml plain">write(sockfd, "hello server", 32);</code>
</div>
<div class="line number89 index88 alt2">
</div>
<div class="line number90 index89 alt1">
<code class="xhtml plain">handle_connection(sockfd);</code>
</div>
<div class="line number91 index90 alt2">
</div>
<div class="line number92 index91 alt1">
<code class="xhtml plain">return 0;</code>
</div>
<div class="line number93 index92 alt2">
<code class="xhtml plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<span><strong>4、程序结果</strong></span></p>
<p>
启动服务程序,执行三个个客户程序进行测试,结果如下图所示:</p>
<p>
<img title="IO多路复用之select全面总结(必看篇)" alt="IO多路复用之select全面总结(必看篇)" src="https://zhuji.jb51.net/uploads/img/202305/b25f4a76a77e0991c1ca28b8f34731a0.jpg"></p>
<p>
以上就是小编为大家带来的io多路复用之select全面总结(必看篇)全部内容了,希望大家多多支持~</p>
頁:
[1]