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‘))
复制代码