马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 MSK 于 2017-6-10 21:26 编辑
上一篇:
threading模块拾遗
socket模块
写一聊天室和你的小伙伴耍耍
socket通常也称作”套接字“。网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。socket 是网络连接端点。例如当你的Web浏览器请求www.fishc.com上的主页时,你的Web浏览器创建一个socket并命令它去连接 www.fishc.com的Web服务器主机,Web服务器也对来自的请求在一个socket上进行监听。两端使用各自的socket来发送和 接收信息。
socket模块提供了几个函数用于使用主机名和地址来工作:
gethostname() 返回运行程序所在的计算机的主机名:
#>>> import socket
#>>> socket.gethostname()
#'李嘉图的计算机'
#>>>
gethostbyname(name) 尝试将给定的主机名解释为一个IP地址
#>>> #socket.gethostbyname('www.fishc.com')
#'101.37.44.185'
#>>> socket.gethostbyname('李嘉图的计算机')
#'192.168.1.104'
#>>>
ps:首先将检查当前计算机是否能够解释。如果不能,一个解释请求将发送给一个远程的DNS服务器(远程的DNS服务器 还可能将解释请求转发给另一个DNS服务器,直到该请求可以被处理)。gethostbyname函数返回这个IP地址或在查找失败后引发一个异常。
拓展;
gethostbyname_ex(name)返回一个包含三个元素的元组 :
(给定地址的主要的主机名,同一IP地址的可选的主机名的一个列,同一主机的同一接口的其它IP地址的一个列表)
>>> #>>>socket.gethostbyname_ex('www.fishc.com')
#('bbgaws7ldwotai4akucb7ckfsnvzoz6m.aliyunwaf.com', ['www.fishc.com'], ['101.37.44.185'])
gethostbyaddr(address)函数的作用与gethostbyname_ex相同,只是你提供给它的参数是一个IP地址字符串
getservbyname(service,protocol)函数要求一个服务名(如'telnet'或'ftp')和一个协议(如'tcp'或'udp'),返回服务所使用的端口号:
#>>>socket.getservbyname('http','tcp')
#80
#>>>socket.getservbyname('telnet','tcp)
#23
socket通信
import socket
1. socket()
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
(1)family = AF_INET表示服务器之间的通信。
(2)fmily = AF_UNIX表示Unix不同进程间的通信。
(3)type = SOCK_STREAM表示TCP连接。
(4)type = SOCK_DGRAM 表示UDP连接。
ps: 2, 3, 4 方法用于服务端
2. bind()
sk.bind(address)
将地址与socket绑定。address(host IP,端口号),address必须是个元组。
3. listen()
listen(backlog)
监听客户端的连接。backlog为可选参数,表示最大等待连接数量。
4.accept()
接受连接并返回(conn,address)。其中conn表示客户端的sk对象,
示例:
sk = socket.socket()
address = ('127.0.0.1',9080)
sk.bind(address)
sk.listen(5)
conn,addr = sk.accept()
print(sk)
print(conn)
print(addr)
输出结果:
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9080)>
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9080), raddr=('127.0.0.1', 35066)>
('127.0.0.1', 35066)
5.recv()
sk.recv(bufsize)
接收数据。其中bufsize表示最大可接收的数据大小。
6.connect()
sk.connect(address)
连接指定地址的socket。address用元组表示。
7.send()
sk.send(data)
将data发送给连接的socket。
8.sendall()
与send类似,内部通过递归调用send()方法,尝试将所有数据发送出去。
9.sendto()
sk.sendto(data,addr)
可指定远端地址
notice!
TCP(SOCK_STREAM),需要连接到远程主机才可以发送数据,发送数据用send(b'字符')
UDP(SOCK_DGRAM),不需要连接,直接发送数据,发送数据用sendto(b'字符',(ip,port))
10.settimeout(timeout)
设置超时。
11.getpeername()
返回远端socket的地址(address,port)。
12.getsockname()
返回自己的socket地址(address,port)。
13.fileno()
套接字的文件描述符。
示例:
利用socket模块进行通信
服务端:
sk = socket.socket()
address = ('127.0.0.1',9080)
sk.bind(address)
sk.listen(5)
conn,addr = sk.accept()
data = conn.recv(1024)
print(str(data,'utf8'))
客户端:
sk = socket.socket()
address = ('127.0.0.1',9080)
sk.connect(address)
inp = input('>>')
sk.send(bytes(inp,'utf8'))
进阶版:
黏包现象
简单的文件传输
|