天天看点

Linux下套接字详解(四)----简单的TCP套接字应用(迭代型) TCP套接字编程模型图 TCP编程流程说明 异常机制 简单的TCP套接字应用程序

前面我们已经将了tcp/udp的基本知识,还说了并发服务器与迭代服务器的区别,我们大致了解大多数tcp服务器是并发的,大多数udp服务器是迭代的 ,即我们在进行数据传送的时候,往往使用服务器与客户但之间无连接的udp报文,但是在用户需要上传下载文件时,就会在客户端和服务器之间建立一条tcp连接,进行文件的传送

那么我们下面就来实现一个简单的tcp服务器。

我们首先看一下tcp客户端与服务端的编程模型和流程。

此模型不仅适合迭代服务器,也适合并发服务器,不管服务器是并发的还是迭代的,两者实现流程类似,只不过并发服务器接收客户请求(accept)后会fork子进程,由子进程处理客户端的请求,而迭代服务器则会一直处理客户端的请求直至请求结束,因此在这期间不会再响应其他客户端的请求。

Linux下套接字详解(四)----简单的TCP套接字应用(迭代型) TCP套接字编程模型图 TCP编程流程说明 异常机制 简单的TCP套接字应用程序

(1)server 服务器端编程流程

tcp服务器端编程流程如下:

① 创建套接字socket;

② 绑定套接字bind;

③ 设置套接字为监听模式,进入被动接受连接状态listen;

④ 接受请求,建立连接accpet;

⑤ 读写数据read/write;

⑥ 终止连接close。

(2) client客户端编程流程

tcp客户端编程流程如下:

② 与远程服务器建立连接connect;

③ 读写数据read/write;

④ 终止连接close。

3) tcp服务器三种异常情况

tcp服务器有三种异常情况,分别为服务器主机崩溃、服务器主机崩溃后重启、服务器主机关机。

服务器主机崩溃

在服务器主机崩溃的情况下,已有的tcp网络连接上发不出任何东西。

此时客户端发出数据后,会一直阻塞在套接字的读取响应。但是由于服务器主机已崩溃,tcp客户端会持续重传数据分节,试图从服务器接收一个ack[一般重传12次(源自berkeley的实现)]后,客户tcp最终选择放弃,返回给应用经常一个etimedout错误;或者是因为中间路由器判定服务器主机不可达,则返回一个目的地不可达的icmp消息响应,其错误代码为ehostunreach或enetunreach。

简单来说,客户端会一直阻塞与read调用,然后一直重传,直到最后超时,客户最终会发现服务器主机已崩溃或主机不可达,然后返回一个状态码,但是这个过程可能是很长就的,解决的方法就是自己写一个read函数然后设置超时,或者加一个so_keepalive选项,也可以通过设置套接字选项可以更改tcp持续重传等待的超时时间。

服务器主机崩溃后重启

在服务器主机崩溃后重启的情况下,如果客户在主机崩溃重启前不主动发送数据,那么客户是不会知道服务器已崩溃。

在服务器重启后,客户向服务器发送一个数据分节;由于服务器重启后丢失了以前的连接信息(尽管在服务端口上有进程监听,但连接套接字所在的端口无进程等待),因此导致服务器主机的tcp响应rst;而客户由于之前未收到服务器的响应数据,页阻塞于read调用,当客户端收到这个rst之后便返回错误econnreset。

如果客户对服务器的崩溃情况很关心,即使客户不主动发送数据也这样,这需要进行相关设置(如设置套接口选项so_keepalive或某些客户/服务器心跳函数)。

服务器主机关机

这里一般指的是正常关机,因为unix系统关机时,会发送sigterm和sigkill信号,sigtrem可能忽略,但是sigkill信号不能忽略,于是服务器将由sigkill终止,

当服务器主机关机的情况下,由于init进程给所有运行的进程发信号sigterm,这时服务器程序可以捕获该信号,并在信号处理程序中正常关闭网络连接。如果服务器程序忽略了sigterm信号,则init进程会等待一段固定的时间(通常是5s~20s),然后给所有还在运行的程序发信号sigkill。服务器将由信号sigkill终止,其终止时,所有打开的描述字被关闭,这导致向客户发送fin分节,客户收到fin分节后,能推断出服务器将终止服务。

我们下面将实现一个迭代类型的简单tcp服务器与客户端,实现客户端从服务器上传/下载文件(我们的程序中主要是上传)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

由于tcp和udp在实现流程上有很多异曲同工之处,因此我们后面的拓展优化将主要针对tcp套接字程序,我们在下一篇开始udp的套接字编程详解,理解了tcp不同的实现思想之后稍加修改即可。。。。
Linux下套接字详解(四)----简单的TCP套接字应用(迭代型) TCP套接字编程模型图 TCP编程流程说明 异常机制 简单的TCP套接字应用程序
Linux下套接字详解(四)----简单的TCP套接字应用(迭代型) TCP套接字编程模型图 TCP编程流程说明 异常机制 简单的TCP套接字应用程序

转载:http://blog.csdn.net/gatieme/article/details/46357249

继续阅读