系列文章

第一章 元类编程,已完成 ;

第二章 网络编程,已完成 ;

本文目录

什么是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进阶开发之网络编程,socket实现在线聊天机器人的更多相关文章

  1. python(38)- 网络编程socket

    一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 美好的愿望: 最常用的软件服务器是 Web 服务器.一台机器里放一些网页或 Web 应用程序 ...

  2. python进阶九_网络编程

    Python网络编程一 一.一些基本概念 在Python网络编程这一节中会涉及到非常多网络相关的术语.对于一些最主要的概念,如TCP/IP,Socket等等不再赘述,不明确的能够自己去查一查,对于一些 ...

  3. python(39)- 网络编程socket练习

    基于tcp的套接字实现远程执行命令的操作 #服务端 import socket import subprocess phone=socket.socket(socket.AF_INET,socket. ...

  4. Python网络编程socket

    网络编程之socket 看到本篇文章的题目是不是很疑惑,what is this?,不要着急,但是记住一说网络编程,你就想socket,socket是实现网络编程的工具,那么什么是socket,什么是 ...

  5. 网络编程socket基本API详解(转)

    网络编程socket基本API详解   socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...

  6. Android 网络编程 Socket

    1.服务端开发 创建一个Java程序 public class MyServer { // 定义保存所有的Socket,与客户端建立连接得到一个Socket public static List< ...

  7. python六十七课——网络编程(基础知识了解)

    网络编程: 什么是网络编程? 网络:它是一种隐形的媒介:可以将多台计算机使用(将它们连接到一起) 网络编程:将多台计算机之间可以相互通信了(做数据交互) 一旦涉及到网络编程,划分为两个方向存在,一方我 ...

  8. 铁乐学Python_Day33_网络编程Socket模块1

    铁乐学Python_Day33_网络编程Socket模块1 部份内容摘自授课老师的博客http://www.cnblogs.com/Eva-J/ 理解socket Socket是应用层与TCP/IP协 ...

  9. 【游戏开发】网络编程之浅谈TCP粘包、拆包问题及其解决方案

    引子 现如今手游开发中网络编程是必不可少的重要一环,如果使用的是TCP协议的话,那么不可避免的就会遇见TCP粘包和拆包的问题,马三觉得haifeiWu博主的 TCP 粘包问题浅析及其解决方案 这篇博客 ...

随机推荐

  1. PCA与特征选取

    一.什么是PCA PCA,即PrincipalComponents Analysis,也就是主成份分析: 通俗的讲,就是寻找一系列的投影方向,高维数据按照这些方向投影后其方差最大化(方差最大的即是第一 ...

  2. HTML入门笔记案例展示(1)

    一: html标签&html书写规则 Html 的标签 分为如下 这两种 : 单标签: 单标签一般 用于特殊的含义,  例如 :  <br/> 表示换行,  <hr/> ...

  3. AngularJS进阶(三十二)书海拾贝之特殊的ng-src和ng-href

    书海拾贝之特殊的ng-src和ng-href 在说明这两个指令的特殊之前,需要先了解一下ng的启动及执行过程,如下: 1) 浏览器加载静态HTML文件并解析为DOM: 2) 浏览器加载angular. ...

  4. (二十四)监听键盘的通知和键盘弹出隐藏的View移动

    让控制器监听键盘的通知,注意谁监听,谁的dealloc方法中就要remove,如果非ARC还要调用父类的dealloc方法. //监听键盘的操作: [[NSNotificationCenter def ...

  5. 查看linux系统是多少位

    . getconf LONG_BIT echo $HOSTTYPE uname -a 这三个是对的 我的是64位

  6. 开源,免费和跨平台 - MVP ComCamp 2015 KEYNOTE

    2015年1月31日,作为KEYNOTE演讲嘉宾,我和来自全国各地的开发人员分享了作为一名MVP的一些体会. Keynote – Open Source, Free Tools and Cross P ...

  7. RecyclerView notifyItem闪烁的问题

    之前我们做点赞,用listview做的话,就是在item实现点击后,写一个scal动画,不过现在都转到RecyclerView,那么要做这种效果于是做了一个notifyItemChanged()的操作 ...

  8. Unity C# 自定义TCP传输协议以及封包拆包、解决粘包问题

    本文只是初步实现了一个简单的TCP自定协议,更为复杂的协议可以根据这种方式去扩展. TCP协议,通俗一点的讲,它是一种基于socket传输的由发送方和接收方事先协商好的一种消息包组成结构,主要由消息头 ...

  9. 操作系统 - 死锁(Deadlock)的概述、条件、对策

    资源 可抢占资源(preemptable resource)可以从拥有它的进程中抢占而不会产生任何副作用,存储器就是一类可抢占的资源.可抢占资源有时有潜在的死锁危险,通常可以通过在进程之间重新分配资源 ...

  10. Android进阶(十七)AndroidAPP开发问题汇总(一)

    首先来看一下猎头公司对于Android方向人才招聘的需求: 猎头公司推荐------资深Java软件工程师(Android方向) 岗位职责: 1.熟悉Java语言,熟悉B/S开发的基本结构 2.能运用 ...