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/
1、Socket 类型
2、Socket 函数
3、socket编程思路
4、Socket编程之服务端代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
root@yangrong:
/
python
# catday5-socket-server.py
#!/usr/bin/python
import
socket
#socket模块
import
commands
#执行系统命令模块
HOST
=
'10.0.0.245'
PORT
=
50007
s
=
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#定义socket类型,网络通信,TCP
s.bind((HOST,PORT))
#套接字绑定的IP与端口
s.listen(
1
)
#开始TCP监听
while
1
:
conn,addr
=
s.accept()
#接受TCP连接,并返回新的套接字与IP地址
print
'Connected by'
,addr
#输出客户端的IP地址
while
1
:
data
=
conn.recv(
1024
)
#把接收的数据实例化
cmd_status,cmd_result
=
commands.getstatusoutput(data)
#commands.getstatusoutput执行系统命令(即shell命令),返回两个结果,第一个是状态,成功则为0,第二个是执行成功或失败的输出信息
if
len
(cmd_result.strip())
=
=
0
:
#如果输出结果长度为0,则告诉客户端完成。此用法针对于创建文件或目录,创建成功不会有输出信息
conn.sendall(
'Done.'
)
else
:
conn.sendall(cmd_result)
#否则就把结果发给对端(即客户端)
conn.close()
#关闭连接
|
5、Socket编程之客户端代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
root@yangrong:
/
python
# catday5-socket-client.py
#!/usr/bin/python
import
socket
HOST
=
'10.0.0.245'
PORT
=
50007
s
=
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#定义socket类型,网络通信,TCP
s.connect((HOST,PORT))
#要连接的IP与端口
while
1
:
cmd
=
raw_input
(
"Please input cmd:"
)
#与人交互,输入命令
s.sendall(cmd)
#把命令发送给对端
data
=
s.recv(
1024
)
#把接收的数据定义为变量
print
data
#输出变量
s.close()
#关闭连接
|
6、执行效果:
7、程序缺限:
socket. AF_UNIX socket. AF_INET(IPV4) socket. AF_INET6(IPV6)
这些常量代表地址簇(和协议),用于 socket() 函数的第一个参数。例如常量 AF_UNIX 没有被定义,那么这个协议就不会被支持了。
socket. SOCK_STREAM(TCP协议,保证数据一定能传到对方) socket. SOCK_DGRAM(广播协议) socket. SOCK_RAW socket. SOCK_RDM socket. SOCK_SEQPACKET
这些常量用于设置 socket 的类型,用于 socket() 函数的第二个参数。(只有SOCK_STREAM和SOCK_DGRAM较为常用)
socket. socket ( [ family [, type [, proto ] ] ] )
Create a new socket using the given address family, socket type and protocol number. The address family should be AF_INET (the default), AF_INET6 orAF_UNIX. The socket type should be SOCK_STREAM (the default), SOCK_DGRAM or perhaps one of the other SOCK_ constants. The protocol number is usually zero and may be omitted in that case.
当通过主调用settimeout()开启某个socket连接的超时选项后,如果这个连接产生了超时行为,那么这个exception就会被引发。所产生的值通常就是很精确的“timed out”字符串。
这个异常由socket related errors引发, 伴随产生的信息会有一个字符串告诉我们什么东西出错了,同时会用一个元组(errno, string)来返回系统调用中导致的错误,与os.error的返回结果类似。可以查看errno模块的相关信息,这个模块包含由操作系统底层定义的error code的名字。
Socket 对象有如下方法。
Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is anew socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.
Bind the socket to address. The socket must not already be bound. (The format of address depends on the address family — see above.)(意思就是address是上面所提到的AF_INET协议族格式或者其它格式,例如“192.168.1.1”,80)
Close the socket. All future operations on the socket object will fail. The remote end will receive no more data (after queued data is flushed). Sockets are automatically closed when they are garbage-collected.
Connect to a remote socket at address. (The format of address depends on the address family — see above.)
-
socket.
getsockname
(
)
-
Return the socket’s own address. This is useful to find out the port number of an IPv4/v6 socket, for instance. (The format of the address returned depends on the address family — see above.)
-
-
socket.
send
(
string
[,
flags
]
)
-
Send data to the socket. The socket mustbe connected to a remote socket. The optional flags argument has the same meaning as for recv() above.Returns the number of bytes sent. Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data. For further information on this concept, consult the Socket Programming HOWTO.
-
-
本文深入解析了Socket编程的基础概念,包括套接字的工作原理、不同类型的Socket及其应用场景,并提供了Python Socket编程的实际示例。

![BU_A_OO1U~D]4P}921LUA)5.jpg 000008836.jpg](https://i-blog.csdnimg.cn/blog_migrate/747ac3f735b253b01ff1b3d6ced5e6a7.jpeg)

526

被折叠的 条评论
为什么被折叠?



