python 简单操作socket
2016-04-13
socket 是什么
socket: 也叫套接字,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。
我也不懂这个定义说的什么鬼话。。。, 让我们通俗点吧。
当两个网络进程需要进行通信(比如client想向server端发送某些请求数据, 由server段进行处理)时, client需要知道server端的ip和port, 然后通过tcp/ip协议发送数据, 网络传输到server端, 由server接收数据, 进而处理。 那么, 客户端如何向tcp/ip 底层发送数据, tcp/ip 又怎么将数据打包(这是 tcp/ip 底层的内容, 实际上应用层是不管这部分的), 然后发送到server端的呢, server端又怎么接收数据,怎么解包, 然后处理呢?
如果我们要关心以上的种种内容, 那么对我们的编程来说, 实在是难啊。 要想能工完整的实现上面的步骤, 我们必须对tcp/ip 协议有完整的理解, 而大多数人都是只听过tcp/ip 这个东西, 并不能完整的理解, 像我也就一知半解。
这就引入了socket, 先人给我们造了这么一个轮子, 他将以上复杂的实现都封装了起来, 只对外暴露了一些简单的接口,然后我们就能跳过上面的种种过程,只需要关系我们业务本身的内容了。
事实上, socket 作为tcp/ip 协议中应用层和网络层之间的接口, 给我们的编程确实带来了极大的方便。给张图更容易理解, 如下:
下面, 我们就用python来简单实现一个server端, 一个client端, 通过client端发送某些数据给server, 并打印出来
server端
所谓的网络进程通信, 基本上就是client 和 server 的通信, 对server端来说, 需要通过ip+port 来定义网络进程, 因为网络中ip 标记主机唯一, 而port则标记了主机的进程的唯一, 两个加起来, 就表示了该进程在网络(大多数都是局域网)中的唯一。
以下是实现(server.py)
sc = socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM) #TCP 网络服务
sc.bind(("127.0.0.1",8888))
sc.listen(5)
sd,addr = sc.accept()
data = sd.recv(1024)
print data
sc.close()
在创建socket对象的时候, 其中有某些参数需要说明以下:
##family:
协议族
,常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址
type
socket类型
定义发送和读取数据的方式, tcp还是udp, 或者其他的方式
下面来说说上面代码的说明
sc = socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM) #TCP 网络服务
sc.bind(("127.0.0.1",8888))
sc.listen(5)
sd,addr = sc.accept()
分别表示
建立一个socket连接
绑定主机端口
设定允许客户端的连接数量,这里是5个
监听端口
这样我们就监听了主机端口8888, 同时, accept
是阻塞运行的, 直至有client的连接发送数据。sd
就表示client与server的连接描述符(类似于我们打开文件,需要先获取文件描述符),通过这个描述符, 就能在client和server读取和发送数据了
data = sd.recv(1024)
print data
sc.close()
表示
读取数据
打印数据
关闭连接
以上就是server端的简单实现, 会阻塞运行, 直至有client 发送数据过来, 打印后关闭连接
client端
client端需要做的就是连接server端, 然后发送数据 以下是实现(client.py)
sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sc.connect(("0.0.0.0",8888))
content = raw_input("plea![图片描述][2]se input something:")
sc.send(content)
没错, 这就是client了, 也很简单, 连接服务器后, 将我们输入的内容发送到服务端
运行
首先运行server端
python server.py
他会阻塞运行
然后我们运行client端
python client.py
运行如下
然后我们在client输入一些内容, 比如hello world
server端就会将内容打印出来
总结
上面我们的server端仅仅是简单的接收了一些字符并输出, 而且没有挂起运行, 打印了一次就关闭了, 如果想挂起运行, 将其放入一个循环体即可
socket 编程给我们的网络进程通信带了了很大的方便, 通过python的socket模块, 我们加深了对cs(client-server) 编程模式的理解, 同时也加深了对socket的理解。
以上就是我使用python对socket编程的理解, 难免有纰漏, 还望各位及时指正