-
-
Notifications
You must be signed in to change notification settings - Fork 80
/
Copy pathsockets.po
588 lines (531 loc) · 35.8 KB
/
sockets.po
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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2001-2021, Python Software Foundation
# This file is distributed under the same license as the Python package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# ww song <sww4718168@gmail.com>, 2019
# df2dc1c92e792f7ae8417c51df43db8f_594d92a <0f49be28017426edb1db1a2ab6e67088_717605>, 2019
# kily zhou <keeliizhou@gmail.com>, 2019
# Alpha Du <alphanow@gmail.com>, 2019
# Freesand Leo <yuqinju@163.com>, 2020
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Python 3.7\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-01 16:02+0000\n"
"PO-Revision-Date: 2019-09-01 03:38+0000\n"
"Last-Translator: Freesand Leo <yuqinju@163.com>, 2020\n"
"Language-Team: Chinese (China) (https://www.transifex.com/python-doc/teams/5390/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_CN\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: ../../howto/sockets.rst:5
msgid "Socket Programming HOWTO"
msgstr "套接字编程指南"
#: ../../howto/sockets.rst:0
msgid "Author"
msgstr "作者"
#: ../../howto/sockets.rst:7
msgid "Gordon McMillan"
msgstr "Gordon McMillan"
#: ../../howto/sockets.rstNone
msgid "Abstract"
msgstr "摘要"
#: ../../howto/sockets.rst:12
msgid ""
"Sockets are used nearly everywhere, but are one of the most severely "
"misunderstood technologies around. This is a 10,000 foot overview of "
"sockets. It's not really a tutorial - you'll still have work to do in "
"getting things operational. It doesn't cover the fine points (and there are "
"a lot of them), but I hope it will give you enough background to begin using"
" them decently."
msgstr ""
"套接字几乎无处不在,但是它却是被误解最严重的技术之一。这是一篇简单的套接字概述。并不是一篇真正的教程 —— "
"你需要做更多的事情才能让它工作起来。其中也并没有涵盖细节(细节会有很多),但是我希望它能提供足够的背景知识,让你像模像样的开始使用套接字"
#: ../../howto/sockets.rst:20
msgid "Sockets"
msgstr "套接字"
#: ../../howto/sockets.rst:22
msgid ""
"I'm only going to talk about INET (i.e. IPv4) sockets, but they account for "
"at least 99% of the sockets in use. And I'll only talk about STREAM (i.e. "
"TCP) sockets - unless you really know what you're doing (in which case this "
"HOWTO isn't for you!), you'll get better behavior and performance from a "
"STREAM socket than anything else. I will try to clear up the mystery of what"
" a socket is, as well as some hints on how to work with blocking and non-"
"blocking sockets. But I'll start by talking about blocking sockets. You'll "
"need to know how they work before dealing with non-blocking sockets."
msgstr ""
"我将只讨论关于 INET(比如:IPv4 地址族)的套接字,但是它将覆盖几乎 99% 的套接字使用场景。并且我将仅讨论 "
"STREAM(比如:TCP)类型的套接字 - 除非你真的知道你在做什么(那么这篇 HOWTO 可能并不适合你),使用 STREAM "
"类型的套接字将会得到比其它类型更好的表现与性能。我将尝试揭开套接字的神秘面纱,也会讲到一些阻塞与非阻塞套接字的使用。但是我将以阻塞套接字为起点开始讨论。只有你了解它是如何工作的以后才能处理非阻塞套接字。"
#: ../../howto/sockets.rst:31
msgid ""
"Part of the trouble with understanding these things is that \"socket\" can "
"mean a number of subtly different things, depending on context. So first, "
"let's make a distinction between a \"client\" socket - an endpoint of a "
"conversation, and a \"server\" socket, which is more like a switchboard "
"operator. The client application (your browser, for example) uses \"client\""
" sockets exclusively; the web server it's talking to uses both \"server\" "
"sockets and \"client\" sockets."
msgstr ""
"理解这些东西的难点之一在于「套接字」可以表示很多微妙差异的东西,这取决于上下文。所以首先,让我们先分清楚「客户端」套接字和「服务端」套接字之间的不同,客户端套接字表示对话的一端,服务端套接字更像是总机接线员。客户端程序只能(比如:你的浏览器)使用「客户端」套接字;网络服务器则可以使用「服务端」套接字和「客户端」套接字来会话"
#: ../../howto/sockets.rst:40
msgid "History"
msgstr "历史"
#: ../../howto/sockets.rst:42
msgid ""
"Of the various forms of :abbr:`IPC (Inter Process Communication)`, sockets "
"are by far the most popular. On any given platform, there are likely to be "
"other forms of IPC that are faster, but for cross-platform communication, "
"sockets are about the only game in town."
msgstr ""
"目前为止,在各种形式的 :abbr:`IPC (进程间通信)` 中,套接字是最流行的。在任何指定的平台上,可能会有其它更快的 IPC "
"形式,但是就跨平台通信来说,套接字大概是唯一的玩法"
#: ../../howto/sockets.rst:47
msgid ""
"They were invented in Berkeley as part of the BSD flavor of Unix. They "
"spread like wildfire with the Internet. With good reason --- the combination"
" of sockets with INET makes talking to arbitrary machines around the world "
"unbelievably easy (at least compared to other schemes)."
msgstr ""
"套接字做为 BSD Unix 操作系统的一部分在伯克利诞生,像野火一样在因特网传播。有一个很好的原因 —— 套接字与 INET "
"的结合使得与世界各地的任意机器间通信变得令人难以置信的简单(至少对比与其他方案来说)"
#: ../../howto/sockets.rst:54
msgid "Creating a Socket"
msgstr "创建套接字"
#: ../../howto/sockets.rst:56
msgid ""
"Roughly speaking, when you clicked on the link that brought you to this "
"page, your browser did something like the following::"
msgstr "简略地说,当你点击带你来到这个页面的链接时,你的浏览器就已经做了下面这几件事情::"
#: ../../howto/sockets.rst:64
msgid ""
"When the ``connect`` completes, the socket ``s`` can be used to send in a "
"request for the text of the page. The same socket will read the reply, and "
"then be destroyed. That's right, destroyed. Client sockets are normally only"
" used for one exchange (or a small set of sequential exchanges)."
msgstr ""
"当连接完成,套接字可以用来发送请求来接收页面上显示的文字。同样是这个套接字也会用来读取响应,最后再被销毁。是的,被销毁了。客户端套接字通常用来做一次交换(或者说一小组序列的交换)。"
#: ../../howto/sockets.rst:70
msgid ""
"What happens in the web server is a bit more complex. First, the web server "
"creates a \"server socket\"::"
msgstr "网络服务器发生了什么这个问题就有点复杂了。首页,服务器创建一个「服务端套接字」::"
#: ../../howto/sockets.rst:80
msgid ""
"A couple things to notice: we used ``socket.gethostname()`` so that the "
"socket would be visible to the outside world. If we had used "
"``s.bind(('localhost', 80))`` or ``s.bind(('127.0.0.1', 80))`` we would "
"still have a \"server\" socket, but one that was only visible within the "
"same machine. ``s.bind(('', 80))`` specifies that the socket is reachable "
"by any address the machine happens to have."
msgstr ""
"有几件事需要注意:我们使用了 ``socket.gethostname()``,所以套接字将外网可见。如果我们使用的是 "
"``s.bind(('localhost', 80))`` 或者 ``s.bind(('127.0.0.1', "
"80))``,也会得到一个「服务端」套接字,但是后者只在同一机器上可见。``s.bind(('', "
"80))`` 则指定套接字可以被机器上的任何地址碰巧连接"
#: ../../howto/sockets.rst:87
msgid ""
"A second thing to note: low number ports are usually reserved for \"well "
"known\" services (HTTP, SNMP etc). If you're playing around, use a nice high"
" number (4 digits)."
msgstr ""
"第二个需要注点是:低端口号通常被一些「常用的」服务(HTTP, SNMP 等)所保留。如果你想把程序跑起来,最好使用一个高位端口号(通常是4位的数字)。"
#: ../../howto/sockets.rst:91
msgid ""
"Finally, the argument to ``listen`` tells the socket library that we want it"
" to queue up as many as 5 connect requests (the normal max) before refusing "
"outside connections. If the rest of the code is written properly, that "
"should be plenty."
msgstr ""
"最后,``listen`` 方法的参数会告诉套接字库,我们希望在队列中累积多达 5 个(通常的最大值)连接请求后再拒绝外部连接。 "
"如果所有其他代码都准确无误,这个队列长度应该是足够的。"
#: ../../howto/sockets.rst:95
msgid ""
"Now that we have a \"server\" socket, listening on port 80, we can enter the"
" mainloop of the web server::"
msgstr "现在我们已经有一个「服务端」套接字,监听了 80 端口,我们可以进入网络服务器的主循环了::"
#: ../../howto/sockets.rst:106
msgid ""
"There's actually 3 general ways in which this loop could work - dispatching "
"a thread to handle ``clientsocket``, create a new process to handle "
"``clientsocket``, or restructure this app to use non-blocking sockets, and "
"multiplex between our \"server\" socket and any active ``clientsocket``\\ s "
"using ``select``. More about that later. The important thing to understand "
"now is this: this is *all* a \"server\" socket does. It doesn't send any "
"data. It doesn't receive any data. It just produces \"client\" sockets. Each"
" ``clientsocket`` is created in response to some *other* \"client\" socket "
"doing a ``connect()`` to the host and port we're bound to. As soon as we've "
"created that ``clientsocket``, we go back to listening for more connections."
" The two \"clients\" are free to chat it up - they are using some "
"dynamically allocated port which will be recycled when the conversation "
"ends."
msgstr ""
"事际上,通常有 3 种方法可以让这个循环工作起来 - 调度一个线程来处理 ``客户端套接字``,或者把这个应用改成使用非阻塞模式套接字,亦或是使用 "
"``select`` 库来实现「服务端」套接字与任意活动 ``客户端套接字`` 之间的多路复用。稍后会详细介绍。现在最重要的是理解:这就是一个 "
"*服务端* 套接字做的 *所有* 事情。它并没有发送任何数据。也没有接收任何数据。它只创建「客户端」套接字。每个 ``客户端套接字`` "
"都是为了响应某些其它客户端套接字 ``connect()`` 到我们绑定的主机。一旦创建 ``客户端套接字`` "
"完成,就会返回并监听更多的连接请求。现个客户端可以随意通信 - 它们使用了一些动态分配的端口,会话结束时端口才会被回收"
#: ../../howto/sockets.rst:121
msgid "IPC"
msgstr "进程间通信"
#: ../../howto/sockets.rst:123
msgid ""
"If you need fast IPC between two processes on one machine, you should look "
"into pipes or shared memory. If you do decide to use AF_INET sockets, bind "
"the \"server\" socket to ``'localhost'``. On most platforms, this will take "
"a shortcut around a couple of layers of network code and be quite a bit "
"faster."
msgstr ""
"如果你需要在同一台机器上进行两个进程间的快速 IPC 通信,你应该了解管道或者共享内存。如果你决定使用 AF_INET "
"类型的套接字,绑定「服务端」套接字到 ``'localhost'`` "
"。在大多数平台,这将会使用一个许多网络层间的通用快捷方式(本地回环地址)并且速度会快很多"
#: ../../howto/sockets.rst:129
msgid ""
"The :mod:`multiprocessing` integrates cross-platform IPC into a higher-level"
" API."
msgstr ":mod:`multiprocessing` 模块使跨平台 IPC 通信成为一个高层的 API"
#: ../../howto/sockets.rst:134
msgid "Using a Socket"
msgstr "使用一个套接字"
#: ../../howto/sockets.rst:136
msgid ""
"The first thing to note, is that the web browser's \"client\" socket and the"
" web server's \"client\" socket are identical beasts. That is, this is a "
"\"peer to peer\" conversation. Or to put it another way, *as the designer, "
"you will have to decide what the rules of etiquette are for a conversation*."
" Normally, the ``connect``\\ ing socket starts the conversation, by sending "
"in a request, or perhaps a signon. But that's a design decision - it's not a"
" rule of sockets."
msgstr ""
"首先需要注意,浏览器的「客户端」套接字和网络服务器的「客户端」套接字是极为相似的。即这种会话是「点对点」的。或者也可以说 "
"*你作为设计师需要自行决定会话的规则和礼节* 。通常情况下,``连接`` "
"套接字通过发送一个请求或者信号来开始一次会话。但这属于设计决定,并不是套接字规则。"
#: ../../howto/sockets.rst:143
msgid ""
"Now there are two sets of verbs to use for communication. You can use "
"``send`` and ``recv``, or you can transform your client socket into a file-"
"like beast and use ``read`` and ``write``. The latter is the way Java "
"presents its sockets. I'm not going to talk about it here, except to warn "
"you that you need to use ``flush`` on sockets. These are buffered \"files\","
" and a common mistake is to ``write`` something, and then ``read`` for a "
"reply. Without a ``flush`` in there, you may wait forever for the reply, "
"because the request may still be in your output buffer."
msgstr ""
"现在有两组用于通信的动词。你可以使用 ``send`` 和 ``recv`` ,或者你可以把客户端套接字改成文件类型的形式来使用 ``read`` 和"
" ``write`` 方法。后者是 Java 语言中表示套接字的方法,我将不会在这儿讨论这个,但是要提醒你需要调用套接字的 ``flush`` "
"方法。这些是“缓冲”的文件,一个经常出现的错误是 ``write`` 一些东西,然后就直接开始 ``read`` 一个响应。如果不调用 "
"``flush`` ,你可能会一直等待这个响应,因为请求可能还在你的输出缓冲中。"
#: ../../howto/sockets.rst:152
msgid ""
"Now we come to the major stumbling block of sockets - ``send`` and ``recv`` "
"operate on the network buffers. They do not necessarily handle all the bytes"
" you hand them (or expect from them), because their major focus is handling "
"the network buffers. In general, they return when the associated network "
"buffers have been filled (``send``) or emptied (``recv``). They then tell "
"you how many bytes they handled. It is *your* responsibility to call them "
"again until your message has been completely dealt with."
msgstr ""
"现在我来到了套接字的两个主要的绊脚石 - ``send`` 和 ``recv`` "
"操作网络缓冲区。它们并不一定可以处理所有你想要(期望)的字节,因为它们主要关注点是处理网络缓冲。通常,它们在关联的网络缓冲区 ``send`` 或者清空"
" ``recv`` 时返回。然后告诉你处理了多少个字节。*你* 的责任是一直调用它们直到你所有的消息处理完成。"
#: ../../howto/sockets.rst:160
msgid ""
"When a ``recv`` returns 0 bytes, it means the other side has closed (or is "
"in the process of closing) the connection. You will not receive any more "
"data on this connection. Ever. You may be able to send data successfully; "
"I'll talk more about this later."
msgstr ""
"当 ``recv`` 方法返回 0 "
"字节时,就表示另一端已经关闭(或者它所在的进程关闭)了连接。你再也不能从这个连接上获取到任何数据了。你可以成功的发送数据;我将在后面讨论这一点。"
#: ../../howto/sockets.rst:165
msgid ""
"A protocol like HTTP uses a socket for only one transfer. The client sends a"
" request, then reads a reply. That's it. The socket is discarded. This "
"means that a client can detect the end of the reply by receiving 0 bytes."
msgstr ""
"像 HTTP 这样的协议只使用一个套接字进行一次传输。客户端发送一个请求,然后读取响应。就这么简单。套接字会被销毁。 表示客户端可以通过接收 0 "
"字节序列表示检测到响应的结束。"
#: ../../howto/sockets.rst:169
msgid ""
"But if you plan to reuse your socket for further transfers, you need to "
"realize that *there is no* :abbr:`EOT (End of Transfer)` *on a socket.* I "
"repeat: if a socket ``send`` or ``recv`` returns after handling 0 bytes, the"
" connection has been broken. If the connection has *not* been broken, you "
"may wait on a ``recv`` forever, because the socket will *not* tell you that "
"there's nothing more to read (for now). Now if you think about that a bit, "
"you'll come to realize a fundamental truth of sockets: *messages must either"
" be fixed length* (yuck), *or be delimited* (shrug), *or indicate how long "
"they are* (much better), *or end by shutting down the connection*. The "
"choice is entirely yours, (but some ways are righter than others)."
msgstr ""
"但是如果你打算在随后来的传输中复用套接字的话,你需要明白 *套接字里面是不存在 :abbr:`EOT (传输结束)`* 的。重复一下:套接字 "
"``send`` 或者 ``recv`` 完 0 字节后返回,连接会中断。如果连接没有被断开,你可能会永远处于等待 ``recv`` "
"的状态,因为(就目前来说)套接字 *不会* "
"告诉你不用再读取了。现在如果你细心一点,你可能会意识到套接字基本事实:*消息必须要么具有固定长度,要么可以界定,要么指定了长度(比较好的做法),要么以关闭连接为结束*。选择完全由你而定(这比让别人定更合理)。"
#: ../../howto/sockets.rst:180
msgid ""
"Assuming you don't want to end the connection, the simplest solution is a "
"fixed length message::"
msgstr "假定你不希望结束连接,那么最简单的解决方案就是使用定长消息::"
#: ../../howto/sockets.rst:217
msgid ""
"The sending code here is usable for almost any messaging scheme - in Python "
"you send strings, and you can use ``len()`` to determine its length (even if"
" it has embedded ``\\0`` characters). It's mostly the receiving code that "
"gets more complex. (And in C, it's not much worse, except you can't use "
"``strlen`` if the message has embedded ``\\0``\\ s.)"
msgstr ""
"发送分部代码几乎可用于任何消息传递方案 —— 在 Python 中你发送字符串,可以使用 ``len()`` 方法来确定它的长度(即使它嵌入了 "
"``\\0`` 字符),主要是接收代码变得更复杂。(在 C 语言中,并没有更糟糕,除非消息嵌入了 ``\\0`` 字符而且你又无法使用 "
"``strlen`` )"
#: ../../howto/sockets.rst:223
msgid ""
"The easiest enhancement is to make the first character of the message an "
"indicator of message type, and have the type determine the length. Now you "
"have two ``recv``\\ s - the first to get (at least) that first character so "
"you can look up the length, and the second in a loop to get the rest. If you"
" decide to go the delimited route, you'll be receiving in some arbitrary "
"chunk size, (4096 or 8192 is frequently a good match for network buffer "
"sizes), and scanning what you've received for a delimiter."
msgstr ""
"最简单的改进是让消息的第一个字符表示消息类型,由类型决定长度。现在你需要两次 ``recv``\\ - "
"第一次取(至少)第一个字符来知晓长度,第二次在循环中获取剩余所有的消息。如果你决定到分界线,你将收到一些任意大小的块,(4096 或者 8192 "
"通常是比较合适的网络缓冲区大小),扫描你接收到的分界符"
#: ../../howto/sockets.rst:231
msgid ""
"One complication to be aware of: if your conversational protocol allows "
"multiple messages to be sent back to back (without some kind of reply), and "
"you pass ``recv`` an arbitrary chunk size, you may end up reading the start "
"of a following message. You'll need to put that aside and hold onto it, "
"until it's needed."
msgstr ""
"一个需要意识到的复杂情况是:如果你的会话协议允许多个消息被发送回来(没有响应),调用 ``recv`` "
"传入任意大小的块,你可能会因为读到后续接收的消息而停止读取。你需要将它放在一边并保存,直到它需要为止。"
#: ../../howto/sockets.rst:237
msgid ""
"Prefixing the message with its length (say, as 5 numeric characters) gets "
"more complex, because (believe it or not), you may not get all 5 characters "
"in one ``recv``. In playing around, you'll get away with it; but in high "
"network loads, your code will very quickly break unless you use two ``recv``"
" loops - the first to determine the length, the second to get the data part "
"of the message. Nasty. This is also when you'll discover that ``send`` does "
"not always manage to get rid of everything in one pass. And despite having "
"read this, you will eventually get bit by it!"
msgstr ""
"以其长度(例如,作为5个数字字符)作为消息前缀时会变得更复杂,因为(信不信由你)你可能无法在一个 ``recv`` "
"中获得所有5个字符。在一般使用时,你会侥幸避免该状况;但是在高网络负载中,除非你使用两个 ``recv`` 循环,否则你的代码将很快中断 —— "
"第一个用于确定长度,第二个用于获取消息的数据部分。这很讨厌。当你发现 ``send`` 并不总是设法在支持搞定一切时,你也会有这种感觉。 "
"尽管已经阅读过这篇文章,但最终还是会有所了解!"
#: ../../howto/sockets.rst:246
msgid ""
"In the interests of space, building your character, (and preserving my "
"competitive position), these enhancements are left as an exercise for the "
"reader. Lets move on to cleaning up."
msgstr "限于篇幅,建立你的角色,(保持与我的竞争位置),这些改进将留给读者做为练习。现在让我们继续。"
#: ../../howto/sockets.rst:252
msgid "Binary Data"
msgstr "二进制数据"
#: ../../howto/sockets.rst:254
msgid ""
"It is perfectly possible to send binary data over a socket. The major "
"problem is that not all machines use the same formats for binary data. For "
"example, a Motorola chip will represent a 16 bit integer with the value 1 as"
" the two hex bytes 00 01. Intel and DEC, however, are byte-reversed - that "
"same 1 is 01 00. Socket libraries have calls for converting 16 and 32 bit "
"integers - ``ntohl, htonl, ntohs, htons`` where \"n\" means *network* and "
"\"h\" means *host*, \"s\" means *short* and \"l\" means *long*. Where "
"network order is host order, these do nothing, but where the machine is "
"byte-reversed, these swap the bytes around appropriately."
msgstr ""
"通过套接字传送二进制数据是可行的。主要问题在于并非所有机器都用同样的二进制数据格式。比如 Motorola 芯片用两个十六进制字节 00 01 "
"来表示一个 16 位整数值 1。而 Intel 和 DEC 则会做字节反转 —— 即用 01 00 来表示 1。套接字库要求转换 16 位和 32 "
"位整数 —— ``ntohl, htonl, ntohs, htons`` 其中的「n」表示 *network*,「h」表示 *host*,「s」表示 "
"*short*,「l」表示 *long*。在网络序列就是主机序列时它们什么都不做,但是如果机器是字节反转的则会适当地交换字节序。"
#: ../../howto/sockets.rst:264
msgid ""
"In these days of 32 bit machines, the ascii representation of binary data is"
" frequently smaller than the binary representation. That's because a "
"surprising amount of the time, all those longs have the value 0, or maybe 1."
" The string \"0\" would be two bytes, while binary is four. Of course, this "
"doesn't fit well with fixed-length messages. Decisions, decisions."
msgstr ""
"在现今的 32 位机器中,二进制数据的 ascii 表示往往比二进制表示要小。这是因为在非常多的时候所有 long 的值均为 0 或者 1。字符串形式的"
" \"0\" 为两个字节,而二进制形式则为四个。当然这不适用于固定长度的信息。自行决定,请自行决定。"
#: ../../howto/sockets.rst:272
msgid "Disconnecting"
msgstr "断开连接"
#: ../../howto/sockets.rst:274
msgid ""
"Strictly speaking, you're supposed to use ``shutdown`` on a socket before "
"you ``close`` it. The ``shutdown`` is an advisory to the socket at the "
"other end. Depending on the argument you pass it, it can mean \"I'm not "
"going to send anymore, but I'll still listen\", or \"I'm not listening, good"
" riddance!\". Most socket libraries, however, are so used to programmers "
"neglecting to use this piece of etiquette that normally a ``close`` is the "
"same as ``shutdown(); close()``. So in most situations, an explicit "
"``shutdown`` is not needed."
msgstr ""
"严格地讲,你应该在 ``close`` 它之前将套接字 ``shutdown`` 。 ``shutdown`` "
"是发送给套接字另一端的一种建议。调用时参数不同意义也不一样,它可能意味着「我不会再发送了,但我仍然会监听」,或者「我没有监听了,真棒!」。然而,大多数套接字库或者程序员都习惯了忽略使用这种礼节,因为通常情况下"
" ``close`` 与 ``shutdown(); close()`` 是一样的。所以在大多数情况下,不需要显式的 ``shutdown`` 。"
#: ../../howto/sockets.rst:282
msgid ""
"One way to use ``shutdown`` effectively is in an HTTP-like exchange. The "
"client sends a request and then does a ``shutdown(1)``. This tells the "
"server \"This client is done sending, but can still receive.\" The server "
"can detect \"EOF\" by a receive of 0 bytes. It can assume it has the "
"complete request. The server sends a reply. If the ``send`` completes "
"successfully then, indeed, the client was still receiving."
msgstr ""
"高效使用 ``shutdown`` 的一种方法是在类似 HTTP 的交换中。客户端发送请求,然后执行 ``shutdown(1)`` 。 "
"这告诉服务器“此客户端已完成发送,但仍可以接收”。服务器可以通过接收 0 字节来检测 “EOF” 。它可以假设它有完整的请求。服务器发送回复。如果 "
"``send`` 成功完成,那么客户端仍在接收。"
#: ../../howto/sockets.rst:289
msgid ""
"Python takes the automatic shutdown a step further, and says that when a "
"socket is garbage collected, it will automatically do a ``close`` if it's "
"needed. But relying on this is a very bad habit. If your socket just "
"disappears without doing a ``close``, the socket at the other end may hang "
"indefinitely, thinking you're just being slow. *Please* ``close`` your "
"sockets when you're done."
msgstr ""
"Python 进一步自动关闭,并说当一个套接字被垃圾收集时,如果需要它会自动执行 ``close`` "
"。但依靠这个机制是一个非常坏的习惯。如果你的套接字在没有 ``close`` "
"的情况下就消失了,那么另一端的套接字可能会无限期地挂起,以为你只是慢了一步。完成后 *请* ``close`` 你的套接字。"
#: ../../howto/sockets.rst:297
msgid "When Sockets Die"
msgstr "套接字何时销毁"
#: ../../howto/sockets.rst:299
msgid ""
"Probably the worst thing about using blocking sockets is what happens when "
"the other side comes down hard (without doing a ``close``). Your socket is "
"likely to hang. TCP is a reliable protocol, and it will wait a long, long "
"time before giving up on a connection. If you're using threads, the entire "
"thread is essentially dead. There's not much you can do about it. As long as"
" you aren't doing something dumb, like holding a lock while doing a blocking"
" read, the thread isn't really consuming much in the way of resources. Do "
"*not* try to kill the thread - part of the reason that threads are more "
"efficient than processes is that they avoid the overhead associated with the"
" automatic recycling of resources. In other words, if you do manage to kill "
"the thread, your whole process is likely to be screwed up."
msgstr ""
"使用阻塞套接字最糟糕的事情可能就是当另一边下线时(没有 ``close`` )会发生什么。你的套接字可能会挂起。 TCP "
"是一种可靠的协议,它会在放弃连接之前等待很长时间。如果你正在使用线程,那么整个线程基本上已经死了。你无能为力。只要你没有做一些愚蠢的事情,比如在进行阻塞读取时持有一个锁,那么线程并没有真正消耗掉资源。"
" *不要* 尝试杀死线程 —— 线程比进程更有效的部分原因是它们避免了与自动回收资源相关的开销。换句话说,如果你设法杀死线程,你的整个进程很可能被搞坏。"
#: ../../howto/sockets.rst:313
msgid "Non-blocking Sockets"
msgstr "非阻塞的套接字"
#: ../../howto/sockets.rst:315
msgid ""
"If you've understood the preceding, you already know most of what you need "
"to know about the mechanics of using sockets. You'll still use the same "
"calls, in much the same ways. It's just that, if you do it right, your app "
"will be almost inside-out."
msgstr ""
"如果你已理解上述内容,那么你已经了解了使用套接字的机制所需了解的大部分内容。你仍将以相同的方式使用相同的函数调用。 "
"只是,如果你做得对,你的应用程序几乎是由内到外的。"
#: ../../howto/sockets.rst:320
msgid ""
"In Python, you use ``socket.setblocking(0)`` to make it non-blocking. In C, "
"it's more complex, (for one thing, you'll need to choose between the BSD "
"flavor ``O_NONBLOCK`` and the almost indistinguishable POSIX flavor "
"``O_NDELAY``, which is completely different from ``TCP_NODELAY``), but it's "
"the exact same idea. You do this after creating the socket, but before using"
" it. (Actually, if you're nuts, you can switch back and forth.)"
msgstr ""
"在 Python 中是使用 ``socket.setblocking(0)`` 来使其为非阻塞。 在 C 中做法更为复杂(例如,你需要在 BSD 风格的"
" ``O_NONBLOCK`` 和几乎无区别的 POSIX 风格的 ``O_NDELAY`` 之间作出选择,这与 ``TCP_NODELAY`` "
"完全不一样。)。 但其思路是完全相同的。 你要在创建套拼字之后但在使用它之前执行此操作。 (实际上,除非你是疯子才会反复切换。)"
#: ../../howto/sockets.rst:327
msgid ""
"The major mechanical difference is that ``send``, ``recv``, ``connect`` and "
"``accept`` can return without having done anything. You have (of course) a "
"number of choices. You can check return code and error codes and generally "
"drive yourself crazy. If you don't believe me, try it sometime. Your app "
"will grow large, buggy and suck CPU. So let's skip the brain-dead solutions "
"and do it right."
msgstr ""
"主要的机制差异是 ``send`` 、 ``recv`` 、 ``connect`` 和 ``accept`` 可以在没有做任何事情的情况下返回。 "
"你(当然)有很多选择。你可以检查返回代码和错误代码,通常会让自己发疯。如果你不相信我,请尝试一下。你的应用程序将变得越来越大、越来越 Bug 、吸干 "
"CPU。因此,让我们跳过脑死亡的解决方案并做正确的事。"
#: ../../howto/sockets.rst:334
msgid "Use ``select``."
msgstr "使用 ``select`` 库"
#: ../../howto/sockets.rst:336
msgid ""
"In C, coding ``select`` is fairly complex. In Python, it's a piece of cake, "
"but it's close enough to the C version that if you understand ``select`` in "
"Python, you'll have little trouble with it in C::"
msgstr ""
"在 C 中,编码 ``select`` 相当复杂。 在 Python 中,它是很简单,但它与 C 版本足够接近,如果你在 Python 中理解 "
"``select`` ,那么在 C 中你会几乎不会遇到麻烦::"
#: ../../howto/sockets.rst:347
msgid ""
"You pass ``select`` three lists: the first contains all sockets that you "
"might want to try reading; the second all the sockets you might want to try "
"writing to, and the last (normally left empty) those that you want to check "
"for errors. You should note that a socket can go into more than one list. "
"The ``select`` call is blocking, but you can give it a timeout. This is "
"generally a sensible thing to do - give it a nice long timeout (say a "
"minute) unless you have good reason to do otherwise."
msgstr ""
"你传递给 ``select`` "
"三个列表:第一个包含你可能想要尝试读取的所有套接字;第二个是你可能想要尝试写入的所有套接字,以及要检查错误的最后一个(通常为空)。你应该注意,套接字可以进入多个列表。"
" ``select`` 调用是阻塞的,但你可以给它一个超时。这通常是一件明智的事情 —— 给它一个很长的超时(比如一分钟),除非你有充分的理由不这样做。"
#: ../../howto/sockets.rst:355
msgid ""
"In return, you will get three lists. They contain the sockets that are "
"actually readable, writable and in error. Each of these lists is a subset "
"(possibly empty) of the corresponding list you passed in."
msgstr "作为返回,你将获得三个列表。它们包含实际可读、可写和有错误的套接字。 这些列表中的每一个都是你传入的相应列表的子集(可能为空)。"
#: ../../howto/sockets.rst:359
msgid ""
"If a socket is in the output readable list, you can be as-close-to-certain-"
"as-we-ever-get-in-this-business that a ``recv`` on that socket will return "
"*something*. Same idea for the writable list. You'll be able to send "
"*something*. Maybe not all you want to, but *something* is better than "
"nothing. (Actually, any reasonably healthy socket will return as writable -"
" it just means outbound network buffer space is available.)"
msgstr ""
"如果一个套接字在输出可读列表中,那么你可以像我们一样接近这个业务,那个套接字上的 ``recv`` 将返回 *一些内容* "
"。可写列表的也相同,你将能够发送 *一些内容* 。 也许不是你想要的全部,但 *有些东西* 比没有东西更好。 "
"(实际上,任何合理健康的套接字都将以可写方式返回 —— 它只是意味着出站网络缓冲区空间可用。)"
#: ../../howto/sockets.rst:366
msgid ""
"If you have a \"server\" socket, put it in the potential_readers list. If it"
" comes out in the readable list, your ``accept`` will (almost certainly) "
"work. If you have created a new socket to ``connect`` to someone else, put "
"it in the potential_writers list. If it shows up in the writable list, you "
"have a decent chance that it has connected."
msgstr ""
"如果你有一个“服务器”套接字,请将其放在 potential_readers 列表中。如果它出现在可读列表中,那么你的 ``accept`` "
"(几乎肯定)会起作用。如果你已经创建了一个新的套接字 ``connect`` 其他人,请将它放在 potential_writers "
"列表中。如果它出现在可写列表中,那么它有可能已连接。"
#: ../../howto/sockets.rst:372
msgid ""
"Actually, ``select`` can be handy even with blocking sockets. It's one way "
"of determining whether you will block - the socket returns as readable when "
"there's something in the buffers. However, this still doesn't help with the"
" problem of determining whether the other end is done, or just busy with "
"something else."
msgstr ""
"实际上,即使使用阻塞套接字, ``select`` 也很方便。这是确定是否阻塞的一种方法 —— "
"当缓冲区中存在某些内容时,套接字返回为可读。然而,这仍然无助于确定另一端是否完成或者只是忙于其他事情的问题。"
#: ../../howto/sockets.rst:377
msgid ""
"**Portability alert**: On Unix, ``select`` works both with the sockets and "
"files. Don't try this on Windows. On Windows, ``select`` works with sockets "
"only. Also note that in C, many of the more advanced socket options are done"
" differently on Windows. In fact, on Windows I usually use threads (which "
"work very, very well) with my sockets."
msgstr ""
"**可移植性警告** :在 Unix 上, ``select`` 适用于套接字和文件。 不要在 Windows 上尝试。在 Windows 上, "
"``select`` 仅适用于套接字。另请注意,在 C 中,许多更高级的套接字选项在 Windows 上的执行方式不同。事实上,在 Windows "
"上我通常在使用我的套接字使用线程(非常非常好)。"