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编程的理解, 难免有纰漏, 还望各位及时指正