首页 / PYTHON / Python进阶开发之网络编程
Python进阶开发之网络编程
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python进阶开发之网络编程,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6411字,纯文字阅读大概需要10分钟。
内容图文
Photo by Dav From Lofter
本文目录
什么是socket?
创建socket客户端
创建socket服务端
socket工作流程图解
socket公共函数汇总
实战:搭建在线聊天机器人
. 什么是socket?
说到网络编程,难免要提到socket
?
那什么是socket呢,中文名叫"套接字
",更难理解了吧。
通俗来讲,socket表示一个网络连接,通过这个连接,使得主机间或者一台计算机上的进程间可以通讯。
不管是不同主机,还是同一主机。既然是通信,必定有一个发送方,一个接收方。对应一个客户端,和一个服务端。
. 创建socket客户端
创建socket,建立连接
1import socket
2
3# 指定IPv4协议(AF_INET),IPv6协议请使用AF_INET6
4# 指定使用TCP协议(SOCK_STREAM),UDP协议请使用SOCK_DGRAM
5sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
6
7# 参数是一个tuple,tuple里指定服务器地址(域名或ip)和端口号
8sock.connect(('www.sina.com.cn', 80))
发送数据
1# 注意这里str格式要遵循HTTP协议标准。
2# 注意结尾一定要用 \r\n\r\n
3sock.send("GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\n\r\n".encode("utf-8"))
接收数据
1buffer = []
2while True:
3 ? ?# 每次最多接收1k字节
4 ? ?d = sock.recv(1024)
5 ? ?if d:
6 ? ? ? ?# Python3接收到为bytes类型,要转为str
7 ? ? ? ?buffer.append(str(d))
8 ? ?else:
9 ? ? ? ?break
10data = ''.join(buffer)
. 创建socket服务端
创建socket
1import socket
2
3sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
绑定ip和port
1# 注意以元组格式传入,可以是某网卡的公网ip,或0.0.0.0,或127.0.0.1
2sock.bind(('127.0.0.1', 9999))
监听端口
1# 指定等待连接的最大数量
2sock.listen(5)
接收数据
1while True:
2 ? ?# 接受一个新连接,阻塞的,只有接收到新连接才会往下走
3 ? ?sock, addr = s.accept()
4 ? ?# 每一次连接,都要创建新线程,否则一次只能处理一个连接
5 ? ?t = threading.Thread(target=tcplink, args=(sock, addr))
6 ? ?t.start()
连接处理函数
1def tcplink(sock, addr):
2 ? ?while True:
3 ? ? ? ?data = sock.recv(1024)
4 ? ? ? ?if data == 'exit' or not data:
5 ? ? ? ? ? ?break
6 ? ? ? ?sock.send('Hello, %s!' % data)
7 ? ?sock.close()
. socket工作流程图解
. socket公共函数汇总
发送数据
1# 发送TCP数据,返回值:发送的字节当量
2sk.send("data string")
3
4# 完整发送TCP数据,频繁调用send方法,确保数据发送完成
5sk.sendall("data string")
6
7# 发送UDP数据
8sk.sendto("data string",address)
接收数据
1# 接收TCP数据,一次最大只接收1k数据
2sk.recv(1024)
3
4# 接收UDP数据,一次只接收1k数据,返回值:数据和发送方ip
5(data,address) = sk.recvfrom(1024)
获取socket信息
1# 获取远程socket的addr,port
2(addr, port) = sk.getpeername()
3
4# 获取本地socket的addr,port
5(addr, port) = sk.getsockname()
获取其他信息
1import socket
2
3# 获取当前主机名
4HostName = socket.gethostname()
5
6# 获取当前主机的ip
7HOST = socket.gethostbyname(HostName)
8
9# 获取当前socket连接的文件描述符
10file_no = sk.fileno()
设置socket
1# 设置连接的超时时间
2sk.settimeout(timeout)
3sk.gettimeout()
4
5# 设置为非阻塞模式,默认是0(阻塞)
6# 非阻塞下,accept和recv时一旦无数据,则报错:socket.Error
7sk.setblocking(1)
8
9# 设置socket内部参数,
10# 具体有哪些参数,可以查看socket类的python源码
11sk.setsockopt(level,optname,value)
12sk.getsockopt(level,optname)
. 实战:搭建在线聊天机器人
通过上面的学习,我们知道,同主机下或不同主机下的两个进程要进行通信(TCP/UDP
,不管是消息传输还是文件传输),必定要借助socket这个桥梁。
那接下来,我们就一起来完成这个实战项目:在线聊天机器人
。
思路:首先,客户端和服务端建立socket连接,然后客户端向服务端发送消息,服务端接收消息,并调用 图灵机器人API接口,获取回复返回给客户端。
在这里,我们需要先去图灵机器人(http://www.tuling123.com
)申请帐号,并创建机器人应用,获取授权码。
一切准备就绪,就可以写我们的代码了。
客户端
1import socket
2import time
3
4class ChatClient:
5 ? ?def __init__(self, username, port):
6 ? ? ? ?self.username = username
7 ? ? ? ?self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
8 ? ? ? ?self.socket.connect(("127.0.0.1", port))
9
10 ? ?def send_msg(self, msg):
11 ? ? ? ?self.socket.send("{username}::{msg}".format(username=self.username,msg=msg).encode("utf-8"))
12
13 ? ?def recv_msg(self):
14 ? ? ? ?data=self.socket.recv(1024)
15 ? ? ? ?if data:
16 ? ? ? ? ? ?print("\n【机器人小图】"+" "+time.strftime('%Y-%m-%d:%H:%M:%S',time.localtime(time.time())))
17 ? ? ? ? ? ?print(data.decode("utf-8"))
18 ? ? ? ? ? ?return True
19 ? ? ? ?return False
20
21 ? ?def main(self):
22 ? ? ? ?data = self.socket.recv(1024)
23 ? ? ? ?print(data.decode("utf-8"))
24 ? ? ? ?msg = input("请输入消息:")
25 ? ? ? ?self.send_msg(msg)
26 ? ? ? ?while True:
27 ? ? ? ? ? ?if self.recv_msg():
28 ? ? ? ? ? ? ? ?msg=input("\n我:")
29 ? ? ? ? ? ? ? ?self.send_msg(msg)
30 ? ? ? ? ? ? ? ?if msg == "exit":
31 ? ? ? ? ? ? ? ? ? ?print("聊天室已关闭")
32 ? ? ? ? ? ? ? ? ? ?break
33
34if __name__ == '__main__':
35 ? ?cc = ChatClient(username="小明", port=9999)
36 ? ?cc.main()
服务端
1import socket
2import time
3import threading
4import requests
5import json
6
7
8class ChatServer:
9 ? ?def __init__(self, port):
10 ? ? ? ?# 绑定服务器的ip和端口,注意以tuple的形式
11 ? ? ? ?self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
12 ? ? ? ?self.socket.bind(("0.0.0.0", port))
13 ? ? ? ?self.socket.listen(5)
14 ? ? ? ?# 图灵机器人,授权码
15 ? ? ? ?self.key = "your tuling robot key"
16 ? ? ? ?print("正在监听 127.0.0.1 :{}...".format(port))
17
18 ? ?def tcplink(self, sock, addr):
19 ? ? ? ?# 每次连接,开始聊天前,先欢迎下。
20 ? ? ? ?sock.send("你好,欢迎来到机器人聊天器!".encode("utf-8"))
21 ? ? ? ?while True:
22 ? ? ? ? ? ?data = sock.recv(1024).decode("utf-8")
23 ? ? ? ? ? ?print(sock.getpeername())
24 ? ? ? ? ? ?print(sock.getsockname())
25 ? ? ? ? ? ?print(sock.fileno())
26 ? ? ? ? ? ?username = data.split("::")[0]
27 ? ? ? ? ? ?msg = data.split("::")[1]
28 ? ? ? ? ? ?if msg == "exit":
29 ? ? ? ? ? ? ? ?break
30 ? ? ? ? ? ?if msg:
31 ? ? ? ? ? ? ? ?print("【"+username+"】 "+time.strftime('%Y-%m-%d:%H:%M:%S',time.localtime(time.time())))
32 ? ? ? ? ? ? ? ?print(msg)
33 ? ? ? ? ? ? ? ?response = self.get_response(msg)
34 ? ? ? ? ? ? ? ?sock.send(response.encode("utf-8"))
35 ? ? ? ?sock.close()
36 ? ? ? ?print("与 {} 结束聊天!".format(username))
37
38 ? ?def get_response(self, info):
39 ? ? ? ?# 调用图灵机器人API
40 ? ? ? ?url = 'http://www.tuling123.com/openapi/api?key=' + self.key + '&info=' + info
41 ? ? ? ?res = requests.get(url)
42 ? ? ? ?res.encoding = 'utf-8'
43 ? ? ? ?jd = json.loads(res.text)
44 ? ? ? ?return jd['text']
45
46 ? ?def main(self):
47 ? ? ? ?while True:
48 ? ? ? ? ? ?sock, addr = self.socket.accept()
49 ? ? ? ? ? ?t=threading.Thread(target=self.tcplink, args=(sock, addr))
50 ? ? ? ? ? ?t.start()
51
52if __name__ == '__main__':
53 ? ?cs = ChatServer(port=9999)
54 ? ?cs.main()
将服务端程序跑起来,然后运行客户端,看下效果。
至此,我们看到我们机器人已经正常和我们调侃。
内容总结
以上是互联网集市为您收集整理的Python进阶开发之网络编程全部内容,希望文章能够帮你解决Python进阶开发之网络编程所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。