Socket的中文名
套接字(socket):源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字。其用于标识客户端请求的服务器和服务它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
socket的作用:
区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。Socket原意是 “插座”。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。(需要源IP,源端口,目的IP,目的端口,协议才能准确区分不同的应用程序(端口号也称作应用程序编号))
官方文档:
socket编程howto:http://python.usyiyi.cn/documents/python_278/howto/sockets.html#socket-howto
Sockets
I’m only going to talk about INET sockets, but they account for at least 99% of the sockets in use.And I’ll only talk about STREAM 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.(本文只涉及Inet socket,但是它已经包含了99%的socket使用)
(关于socket 的 block 和 non-block:By default, socket operations are blocking: when the thread calls a method like connect
orrecv
, it pauses until the operation completes.2 block的意义是socket在调用一个方法后会一直等待这个socket操作完成才会进行下一步操作)
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.(浏览器只使用client socket,而服务器同时使用client socket和server scoket)
Creating a Socket
Roughly speaking, when you clicked on the link that brought you to this page, your browser did something like the following:(当你在访问这个链接的时候,浏览器做了以下的事情)
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).(当这个连接完成的时候,这个叫做s的socket就可以用来发送获取页面文本的请求,这个socket也会读取回复。在这之后,这个socke就会被销毁。注意,每个socket一般在进行一次信息交换后就会被销毁)
What happens in the web server is a bit more complex. First, the web server creates a “server socket”:(server socket的创建更加麻烦一些)
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(我们应该用socket.gethostname()来创建server socket,这样能使得服务器在网络上是可见的)
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).(很多小于3位数的端口已经被保留作为一些特定用途,个人用途最好使用4digts以上的端口)
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.(listen方法告诉server socket它能够同时处理5个connet请求,剩余的请求会被服务器拒绝)
Now that we have a “server” socket, listening on port 80, we can enter the mainloop of the web server:
There’s actually 3 general ways in which this loop could work - dispatching a thread to handleclientsocket, create a new process to handle clientsocket, or restructure this app to use non-blocking sockets,(server socket一般有3种方式处理请求:分配一个线程处理clientsocket,创建一个进程处理clentsocket,或者让这个软件使用non-blocking sockets)
IPC (Inter-Process Communication,进程间通信)
If you need fast IPC between two processes on one machine, you should look into whatever form of shared memory the platform offers. A simple protocol based around shared memory and locks or semaphores is by far the fastest technique.
If you do decide to use 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.(在一台机器上进行进程间通信的时候,你可以使用socket的localhost )
Using a Socket
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.(首先要注意的是,你的浏览器使用的client socket和服务器的clent socket是同样的东西,这是一种对等网络)
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. (现在我们有两种使用socket 通信的方式 send 和 recv,或者你也可以把socket 转换为一种类似文件IO的对象,并使用熟悉的文件IO操作read和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 useflush 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.
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.(现在,让我们看看socket最让人头疼的部分,send和recv操作。send和recv操作)
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.(当socket的recv方法返回0字节的时候,这个socket已经被销毁了,虽然你仍然可以发送数据)
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.(很多协议比如http协议都只用socket做一次数据交换,交换完成之后,这个socket就被销毁了)
But if you plan to reuse your socket for further transfers, you need to realize that there is no EOT 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).(但如果你想要再次使用这个socket继续传输,你需要明白当socket 的 send 和recv都返回0的时候,这个socket已经失效了。否则的话,recv要么会返回完整长度的数据,要么会返回部分长度的数据,要么返回数据的长度)
一个send模型
大牛博客:http://yangrong.blog.51cto.com/6945369/1339593/