套接字介绍
对TCP/IP、UDP、Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。那么我想问:
1. 什么是TCP/IP、UDP?
2. Socket在哪里呢?
3. Socket是什么呢?
4. 你会使用它们吗?
什么是TCP/IP、UDP?
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
这里有一张图,表明了这些协议的关系。
图1
TCP/IP协议族包括运输层、网络层、链路层。现在你知道TCP/IP与UDP的关系了吧。
Socket在哪里呢?
在图1中,我们没有看到Socket的影子,那么它到底在哪里呢?还是用图来说话,一目了然。
图2
原来Socket在这里。
Socket是什么呢?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
你会使用它们吗?
前人已经给我们做了好多的事了,网络间的通信也就简单了许多,但毕竟还是有挺多工作要做的。以前听到Socket编程,觉得它是比较高深的编程知识,但是只要弄清Socket编程的工作原理,神秘的面纱也就揭开了。
一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。 生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。
图3
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
Python的套接字模块
1、Socket 类型
2、Socket 函数
|
Python的套接字实现
我们的套接字编程分为服务器和客户端两部分。
服务器端;
1. 建立socket, s = socket.socket()
2.绑定端口, s.bind( (host, port) )
3.监听端口, s.listen()
4.进入循环,不断接受客户端请求, s.accept()
5.建立连接,接收传来的数据,发送数据 s.recv(), s.sendall()
'''服务器端先初始化socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞
等待客户端连接。这事如果有客户端初始化一个socket,且尝试连接服务器(connect),如果连接成功,
这时客户端与服务器端的连接就建立了。
客户端端发送数据请求,服务器端接收并处理请求,然后把回应数据发给客户端,客户端读取数据,最后关闭连接,
交互结束'''
import socket
import subprocess #执行系统命令模块
HOST = '127.0.0.1'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#服务器之间网络通信,流式socket(TCP)
s.bind((HOST, PORT))
s.listen(1)
while 1:
conn, addr = s.accept() #接受TCP连接,并返回新的套接字与ip地址
print("connected by", addr)
while 1:
data = conn.recv(1024)
#接受套接字的数据,数据以字符串刑事返回,1024指要接受的最大数据量
proc_status,proc_result = subprocess.getstatusoutput(data)
#返回两个结果,第一个是状态,成功则为0,第二个是执行成功或失败的输出信息
if len(proc_result.strip()) == 0:
<span style="white-space:pre"> </span>#如果输出结果长度为0,则告诉客户端完成。
#此用法针对于创建文件或目录,创建成功不会有输出信息
conn.sendall('Done')
#完整发送TCP数据,将string中的数据发送到连接的套接字
#但在返回之前会尝试发送所有数据,成功则返回None,失败则抛出异常
else:
conn.sendall(proc_resut)
conn.close()
>>> help(subprocess.getstatusoutput)Help on function getstatusoutput in module subprocess:
getstatusoutput(cmd)
Return (status, output) of executing cmd in a shell.
Execute the string 'cmd' in a shell with os.popen() and return a 2-tuple
(status, output). cmd is actually run as '{ cmd ; } 2>&1', so that the
returned output will contain output or error messages. A trailing newline
is stripped from the output. The exit status for the command can be
interpreted according to the rules for the C function wait(). Example:
>>> import subprocess
>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> subprocess.getstatusoutput('cat /bin/junk')
(256, 'cat: /bin/junk: No such file or directory')
>>> subprocess.getstatusoutput('/bin/junk')
(256, 'sh: /bin/junk: not found')
subprocess.getstatusoutput(command)
使用os. getstatusoutput ()函数执行command命令并返回一个元组(status,output),
分别表示command命令执行的返回状态和执行结果。对command的执行实际上是按照{command;}
2>&1的方式,所以output中包含控制台输出信息或者错误信息。output中不包含尾部的换行符。
客户端:
1. 建立socket并绑定端口, s = socket.socket(), s.bind()
2. 连接后发送和接收数据 s.sendall(), s.recv()
3.传输完毕,关闭套接字 s.close()
import socket
HOST = '127.0.0.1'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while 1:
cmd = input("Please input command: ")
s.sendall(cmd)
data = s.recv()
print(data)
s.close()