@@ -98,16 +98,18 @@ msgid ""
9898" of sockets with INET makes talking to arbitrary machines around the world "
9999"unbelievably easy (at least compared to other schemes)."
100100msgstr ""
101+ "套接字做为 BSD Unix 操作系统的一部分在伯克利诞生,像野火一样在因特网传播。有一个很好的原因 —— 套接字与 INET "
102+ "的结合使得与世界各地的任意机器间通信变得令人难以置信的简单(至少对比与其他方案来说)"
101103
102104#: ../../howto/sockets.rst:54
103105msgid "Creating a Socket"
104- msgstr ""
106+ msgstr "创建套接字 "
105107
106108#: ../../howto/sockets.rst:56
107109msgid ""
108110"Roughly speaking, when you clicked on the link that brought you to this "
109111"page, your browser did something like the following::"
110- msgstr ""
112+ msgstr "简略地说,当你点击带你来到这个页面的链接时,你的浏览器就已经做了下面这几件事情:: "
111113
112114#: ../../howto/sockets.rst:64
113115msgid ""
@@ -116,12 +118,13 @@ msgid ""
116118"then be destroyed. That's right, destroyed. Client sockets are normally only"
117119" used for one exchange (or a small set of sequential exchanges)."
118120msgstr ""
121+ "当连接完成,套接字可以用来发送请求来接收页面上显示的文字。同样是这个套接字也会用来读取响应,最后再被销毁。是的,被销毁了。客户端套接字通常用来做一次交换(或者说一小组序列的交换)。"
119122
120123#: ../../howto/sockets.rst:70
121124msgid ""
122125"What happens in the web server is a bit more complex. First, the web server "
123126"creates a \" server socket\" ::"
124- msgstr ""
127+ msgstr "网络服务器发生了什么这个问题就有点复杂了。首页,服务器创建一个「服务端套接字」:: "
125128
126129#: ../../howto/sockets.rst:80
127130msgid ""
@@ -132,13 +135,18 @@ msgid ""
132135"same machine. ``s.bind(('', 80))`` specifies that the socket is reachable "
133136"by any address the machine happens to have."
134137msgstr ""
138+ "有几件事需要注意:我们使用了 ``socket.gethostname()``,所以套接字将外网可见。如果我们使用的是 "
139+ "``s.bind(('localhost', 80))`` 或者 ``s.bind(('127.0.0.1', "
140+ "80))``,也会得到一个「服务端」套接字,但是后者只在同一机器上可见。``s.bind(('', 80))`` "
141+ "则指定套接字可以被机器上的任何地址碰巧连接"
135142
136143#: ../../howto/sockets.rst:87
137144msgid ""
138145"A second thing to note: low number ports are usually reserved for \" well "
139146"known\" services (HTTP, SNMP etc). If you're playing around, use a nice high"
140147" number (4 digits)."
141148msgstr ""
149+ "第二个需要注点是:低端口号通常被一些「常用的」服务(HTTP, SNMP 等)所保留。如果你想把程序跑起来,最好使用一个高位端口号(通常是4位的数字)。"
142150
143151#: ../../howto/sockets.rst:91
144152msgid ""
@@ -147,12 +155,14 @@ msgid ""
147155"outside connections. If the rest of the code is written properly, that "
148156"should be plenty."
149157msgstr ""
158+ "最后,``listen`` 方法的参数会告诉套接字库,我们希望在拒绝外部请求连接前最多使用 5 "
159+ "个连接请求的队列。如果所有的代码都要正确的写出来,代码量将会很大。"
150160
151161#: ../../howto/sockets.rst:95
152162msgid ""
153163"Now that we have a \" server\" socket, listening on port 80, we can enter the"
154164" mainloop of the web server::"
155- msgstr ""
165+ msgstr "现在我们已经有一个「服务端」套接字,监听了 80 端口,我们可以进入网络服务器的主循环了:: "
156166
157167#: ../../howto/sockets.rst:106
158168msgid ""
@@ -170,10 +180,15 @@ msgid ""
170180"dynamically allocated port which will be recycled when the conversation "
171181"ends."
172182msgstr ""
183+ "事际上,通常有 3 种方法可以让这个循环工作起来 - 调度一个线程来处理 ``客户端套接字``,或者把这个应用改成使用非阻塞模式套接字,亦或是使用 "
184+ "``select`` 库来实现「服务端」套接字与任意活动 ``客户端套接字`` 之间的多路复用。稍后会详细介绍。现在最重要的是理解:这就是一个 "
185+ "*服务端* 套接字做的 *所有* 事情。它并没有发送任何数据。也没有接收任何数据。它只创建「客户端」套接字。每个 ``客户端套接字`` "
186+ "都是为了响应某些其它客户端套接字 ``connect()`` 到我们绑定的主机。一旦创建 ``客户端套接字`` "
187+ "完成,就会返回并监听更多的连接请求。现个客户端可以随意通信 - 它们使用了一些动态分配的端口,会话结束时端口才会被回收"
173188
174189#: ../../howto/sockets.rst:121
175190msgid "IPC"
176- msgstr ""
191+ msgstr "进程间通信 "
177192
178193#: ../../howto/sockets.rst:123
179194msgid ""
@@ -183,16 +198,19 @@ msgid ""
183198"a shortcut around a couple of layers of network code and be quite a bit "
184199"faster."
185200msgstr ""
201+ "如果你需要在同一台机器上进行两个进程间的快速 IPC 通信,你应该了解管道或者共享内存。如果你决定使用 AF_INET "
202+ "类型的套接字,绑定「服务端」套接字到 ``'localhost'`` "
203+ "。在大多数平台,这将会使用一个许多网络层间的通用快捷方式(本地回环地址)并且速度会快很多"
186204
187205#: ../../howto/sockets.rst:129
188206msgid ""
189207"The :mod:`multiprocessing` integrates cross-platform IPC into a higher-level"
190208" API."
191- msgstr ""
209+ msgstr ":mod:`multiprocessing` 模块使跨平台 IPC 通信成为一个高层的 API "
192210
193211#: ../../howto/sockets.rst:134
194212msgid "Using a Socket"
195- msgstr ""
213+ msgstr "使用一个套接字 "
196214
197215#: ../../howto/sockets.rst:136
198216msgid ""
@@ -204,6 +222,7 @@ msgid ""
204222"in a request, or perhaps a signon. But that's a design decision - it's not a"
205223" rule of sockets."
206224msgstr ""
225+ "第一个需要注意的的,浏览器的「客户端」套接字和网络服务器的「客户端」套接字一样令信讨厌。也就是说,这是一次「点对点」的会话。换句话说,*做为一个设计师,你将不得不决定一次会话的规则*。一般来说,``连接``中的套接字通过发送一个请求,或者信号开始这次会话。但是这是设计决定的,并不是套接字的规则"
207226
208227#: ../../howto/sockets.rst:143
209228msgid ""
@@ -216,6 +235,10 @@ msgid ""
216235"reply. Without a ``flush`` in there, you may wait forever for the reply, "
217236"because the request may still be in your output buffer."
218237msgstr ""
238+ "现在有两组用于通信的动词。你可以使用 ``send`` 和 ``recv``,或者你可以把客户端套接字改成文件类型的怪东西来使用 ``read`` 和"
239+ " ``write`` 方法。后者是 Java 语言中表示套接字的方法,在这儿我将不会讨论这个,但是要提醒你需要调用套接字的 ``flush`` "
240+ "方法,这些是缓冲区的文件,一个经常出现的错误是 ``write`` 一些东西,然后不调用 ``flush`` 就开始 ``read`` "
241+ "一个响应,你可能会为了这个响应一直等待,因为请求可能还在你的输出缓冲中。"
219242
220243#: ../../howto/sockets.rst:152
221244msgid ""
@@ -227,6 +250,9 @@ msgid ""
227250"you how many bytes they handled. It is *your* responsibility to call them "
228251"again until your message has been completely dealt with."
229252msgstr ""
253+ "现在我来到了套接字的两个主要的绊脚石 - ``send`` 和 ``recv`` "
254+ "操作网络缓冲区。它们并不一定可以处理所有你想要(期望)的字节,因为它们主要关注点是处理网络缓冲。通常,它们在关联的网络缓冲区 ``send`` 或者清空"
255+ " ``recv`` 时返回。然后告诉你处理了多少个字节。*你* 的责任是一直调用它们直到你所有的消息处理完成。"
230256
231257#: ../../howto/sockets.rst:160
232258msgid ""
@@ -235,13 +261,17 @@ msgid ""
235261"data on this connection. Ever. You may be able to send data successfully; "
236262"I'll talk more about this later."
237263msgstr ""
264+ "当 ``recv`` 方法返回 0 "
265+ "字节时,就表示另一端已经关闭(或者它所在的进程关闭)了连接。你再也不能从这个连接上获取到任何数据了。你可以成功的发送数据;我将在后面讨论这一点。"
238266
239267#: ../../howto/sockets.rst:165
240268msgid ""
241269"A protocol like HTTP uses a socket for only one transfer. The client sends a"
242270" request, then reads a reply. That's it. The socket is discarded. This "
243271"means that a client can detect the end of the reply by receiving 0 bytes."
244272msgstr ""
273+ "像 HTTP 这样的协议只使用一个套接字进行一次传输。客户端发送一个请求,然后读取响应。就这么简单。套接字会被销毁。 表示客户端可以通过接收 0 "
274+ "字节序列表示检测到响应的结束。"
245275
246276#: ../../howto/sockets.rst:169
247277msgid ""
@@ -256,12 +286,16 @@ msgid ""
256286"they are* (much better), *or end by shutting down the connection*. The "
257287"choice is entirely yours, (but some ways are righter than others)."
258288msgstr ""
289+ "但是如果你打算在随后来的传输中复用套接字的话,你需要明白 *套接字里面是不存在 :abbr:`EOT (传输结束)`* 的。重复一下:套接字 "
290+ "``send`` 或者 ``recv`` 完 0 字节后返回,连接会中断。如果连接没有被断开,你可能会永远处于等待 ``recv`` "
291+ "的状态,因为(就目前来说)套接字 *不会* "
292+ "告诉你不用再读取了。现在如果你细心一点,你可能会意识到套接字基本事实:*消息必须要么具有固定长度,要么可以界定,要么指定了长度(比较好的做法),要么以关闭连接为结束*。选择完全由你而定(这比让别人定更合理)"
259293
260294#: ../../howto/sockets.rst:180
261295msgid ""
262296"Assuming you don't want to end the connection, the simplest solution is a "
263297"fixed length message::"
264- msgstr ""
298+ msgstr "假定你不希望结束连接,那么最简单的解决方案就是使用定长消息:: "
265299
266300#: ../../howto/sockets.rst:217
267301msgid ""
@@ -271,6 +305,9 @@ msgid ""
271305"gets more complex. (And in C, it's not much worse, except you can't use "
272306"``strlen`` if the message has embedded ``\\ 0``\\ s.)"
273307msgstr ""
308+ "发送分部代码几乎可用于任何消息传递方案 - 在 Python 中你发送字符串,可以使用 ``len()`` 方法来确定它的长度(即使它嵌入了 ``\\ "
309+ "0`` 字符)。主要是接收代码变得更复杂。(在 C 语言中,并没有太糟糕,除非消息嵌入了 ``\\ 0`` 字符而且你又无法使用 ``strlen`` "
310+ ")"
274311
275312#: ../../howto/sockets.rst:223
276313msgid ""
@@ -282,6 +319,9 @@ msgid ""
282319"chunk size, (4096 or 8192 is frequently a good match for network buffer "
283320"sizes), and scanning what you've received for a delimiter."
284321msgstr ""
322+ "最简单的改进是让消息的第一个字符表示消息类型,由类型决定长度。现在你需要两次 ``recv`` - "
323+ "第一次取首字符来知晓长度,第二次在循环中获取剩余所有的消息。如果你决定到分界线,你将收到一些任意大小的块,(4096 或者 8192 "
324+ "通常是比较合适的网络缓冲区大小),扫描你接收到的分界符"
285325
286326#: ../../howto/sockets.rst:231
287327msgid ""
@@ -291,6 +331,8 @@ msgid ""
291331"of a following message. You'll need to put that aside and hold onto it, "
292332"until it's needed."
293333msgstr ""
334+ "一个需要意识到的复杂情况是:如果你的会话协议允许多个消息被发送回来(没有响应),调用 ``recv`` "
335+ "传入任意大小的块儿,你可能会因为读到后续接收的消息而停止读取。你需要将它放在一边并保存,直到它需要为止。"
294336
295337#: ../../howto/sockets.rst:237
296338msgid ""
@@ -303,17 +345,21 @@ msgid ""
303345"not always manage to get rid of everything in one pass. And despite having "
304346"read this, you will eventually get bit by it!"
305347msgstr ""
348+ "用消息的长度做为消息的前缀(比如说,5个数字字符)会更复杂,因为,你可能在一次 ``recv`` 中没法取完这 5 "
349+ "个字符,为了能把程序跑起来,你将设法避免这种情况;但是在高负载的网络中,除非你使用两个``recv`` 循环 - "
350+ "第一个用来确定消息长度,第二个用来获取消息体的数据,否则你的代码会很快中断。真讨厌,这也是当你发现 ``send`` "
351+ "方法并不总是在一个地方处理所有的东西的感觉。尽管你读过这篇文章,但最终还是会有所了解"
306352
307353#: ../../howto/sockets.rst:246
308354msgid ""
309355"In the interests of space, building your character, (and preserving my "
310356"competitive position), these enhancements are left as an exercise for the "
311357"reader. Lets move on to cleaning up."
312- msgstr ""
358+ msgstr "限于篇幅,建立你的角色,(保持与我的竞争位置),这些改进将留给读者做为练习。让我们继续。 "
313359
314360#: ../../howto/sockets.rst:252
315361msgid "Binary Data"
316- msgstr ""
362+ msgstr "二进制数据 "
317363
318364#: ../../howto/sockets.rst:254
319365msgid ""
@@ -327,6 +373,10 @@ msgid ""
327373"network order is host order, these do nothing, but where the machine is "
328374"byte-reversed, these swap the bytes around appropriately."
329375msgstr ""
376+ "能过套接字传送二进制数据是很正常的。主要的问题在于并不是所有的机器都用同样的二进制数据格式。比如,摩托罗拉芯片用 1 做为两个十六进制字节 00 01 "
377+ "来表示一个 16 位整型。然而英特尔和迪吉多,是字节反转的 - 1 是 01 00。套接字库要求转换 16 位和 32 位整数 - ``ntohl, "
378+ "htonl, ntohs, htons`` 其中的 「n」表示 *network*,「h」表示 *host*,「s」表示 *short*,「l」表示 "
379+ "*long*。网络序列就是主机的序列的话它们什么都不做,但是如果机器是字节反转的,它们会适当地交换字节序"
330380
331381#: ../../howto/sockets.rst:264
332382msgid ""
@@ -335,7 +385,7 @@ msgid ""
335385"surprising amount of the time, all those longs have the value 0, or maybe 1."
336386" The string \" 0\" would be two bytes, while binary is four. Of course, this "
337387"doesn't fit well with fixed-length messages. Decisions, decisions."
338- msgstr ""
388+ msgstr "在现代的 32 位机器中,ascii 形式的二进制数据通常小于二进制形式 "
339389
340390#: ../../howto/sockets.rst:272
341391msgid "Disconnecting"
0 commit comments