Python学习之==>Socket网络编程

一、计算机网络

  多台独立的计算机通过网络通信设备连接起来的网络。实现资源共享和数据传递。在同一台电脑上可以将D盘上的一个文件传到C盘,但如果想从一台电脑传一个文件到另外一台电脑上就要通过计算机网络

二、网络编程

  所谓网络编程就是通过某种计算机语言来实现不同设备间的资源共享和信息传递。计算机网络的创造比计算机本身的意义更大,否则我们现在还玩着单机游戏,也没有现在蒸蒸日上的互联网行业。

1、OSI模型

  OSI模型定义了不同计算机互联的标准,是设计和描述计算机网络通信的基本框架。OSI模型把网络通信的工作分为7层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

2、网络通信三要素

A:IP地址

  • 用来标识网络上一台独立的主机;
  • IP地址 = 网络地址 + 主机地址(网络地址:用于识别主机所在的网络/网段。主机地址:用于识别该网络中的主机);
  • 特殊IP地址:127.0.0.1(本地回环地址),表示本机。

B:端口号

  • 用于标识进程的逻辑地址。不同的进程都有不同的端口标识;
  • 要将数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这些数字,则将这些数字称为端口。(此端口是一个逻辑端口)。

C:传输协议 

  • 通讯的规则。例如:TCP、UDP协议(好比两个人得用同一种语言进行交流)。

3、传输协议

A:UDP:User Datagram Protocol用户数据报协议

  • 面向无连接:传输数据之前源端和目的端不需要建立连接;
  • 每个数据报的大小都限制在64K(8个字节)以内;
  • 传输速率快,效率高;
  • 面向报文的不可靠协议(即:发送出去的数据不一定会接收得到);
  • 实例:邮局寄件、实时在线聊天、视频会议…等。

B:TCP:Transmission Control Protocol传输控制协议

  • 面向连接:传输数据之前需要建立连接;
  • 在连接过程中进行大量数据传输;
  • 通过“三次握手”的方式完成连接,是安全可靠协议;
  • 传输速度慢,效率低。

C:TCP协议三次握手过程

  • 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers);
  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手;
  • 完成三次握手,客户端与服务器开始传送数据。

4、网络通讯步骤

  确定对端IP地址→ 确定应用程序端口 → 确定通讯协议

  总结:网络通讯的过程其实就是一个(源端)不断封装数据包和(目的端)不断拆数据包的过程。

  简单来说就是:发送方利用应用软件将上层应用程序产生的数据前后加上相应的层标识不断的往下层传输(封包过程),最终到达物理层通过看得见摸得着的物理层设备,例如:网线、光纤…等将数据包传输到数据接收方,然后接收方则通过完全相反的操作不断的读取和去除每一层的标识信息(拆包过程),最终将数据传递到最高层的指定的应用程序端口,并进行处理。

三、Socket编程

  要想理解socket,就要先来理解TCP/IP协议。

  TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准。
从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族。不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中。

  • 应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等;
  • 传输层:TCP,UDP;
  • 网络层:IP,ICMP,OSPF,EIGRP,IGMP;
  • 数据链路层:SLIP,CSLIP,PPP,MTU;
  • 每一抽象层建立在低一层提供的服务上,并且为高一层提供服务,看起来大概是这样子的。

  我们可以利用ip地址+端口号+协议唯一标示网络中的一个进程。能够唯一标示网络中的进程后,它们就可以利用socket进行通信了,我们经常把socket翻译为套接字,socket是在应用层和传输层(TCP/IP协议族通信)之间的一个抽象层,是一组接口,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

  应用程序两端通过“套接字”向网络发出请求或者应答网络请求。可以把socket理解为通信的把手(hand)。

  socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。socket的英文原义是“插槽”或“插座”,就像我们家里座机一样,如果没有网线的那个插口,电话是无法通信的。Socket是实现TCP,UDP协议的接口,便于使用TCP,UDP。

1、Socket通信流程

2、流程描述

  • 服务器根据地址类型(ipv4,ipv6)、socket类型、协议创建socket;
  • 服务器为socket绑定ip地址和端口号;
  • 服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有被打开;
  • 客户端创建socket;
  • 客户端打开socket,根据服务器IP地址和端口号试图连接服务器socket;
  • 服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()方法一直等到客户端返回连接信息后才返回,开始接收下一个客户端连接请求;
  • 客户端连接成功,向服务器发送连接状态信息;
  • 服务器accept方法返回,连接成功;
  • 客户端向socket写入信息(或服务端向socket写入信息);
  • 服务器读取信息(客户端读取信息);
  • 客户端关闭;
  • 服务器端关闭;

3、相关方法及参数介绍

 1 socket.socket()
 2    # 有family, type, proto, fileno四个参数,其中前两个参数如下:
 3    # family=AF_INET:服务器之间的通信
 4    # family=AF_INET:Unix不同进程间通信
 5    # type=SOCK_STREAM:TCP
 6    # type=SOCK_Dgram:UDP
 7
 8 sk.bind(address)
 9   #s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。
10
11 sk.listen(backlog)
12   #开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
13    #backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
14    #这个值不能无限大,因为要在内核中维护连接队列
15
16 sk.setblocking(bool)
17   #是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
18
19 sk.accept()
20   #接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
21   #接收TCP 客户的连接(阻塞式)等待连接的到来
22
23 sk.connect(address)
24   #连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
25
26 sk.connect_ex(address)
27   #同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061
28
29 sk.close()
30   #关闭套接字
31
32 sk.recv(bufsize[,flag])
33   #接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。
34
35 sk.recvfrom(bufsize[.flag])
36   #与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
37
38 sk.send(string[,flag])
39   #将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。
40
41 sk.sendall(string[,flag])
42   #将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
43        #内部通过递归调用send,将所有内容发送出去。
44
45 sk.sendto(string[,flag],address)
46   #将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。
47
48 sk.settimeout(timeout)
49   #设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )
50
51 sk.getpeername()
52   #返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
53
54 sk.getsockname()
55   #返回套接字自己的地址。通常是一个元组(ipaddr,port)
56
57 sk.fileno()
58   #套接字的文件描述符

四、实例

1、实例一:一次聊天就结束

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 为socket绑定IP和端口号
 7 sk.bind(address)
 8 # 监听端口等待客户端的请求
 9 sk.listen(3)  # 3代表排队的人数
10 print(‘waiting.....‘)
11 # accept阻塞,等待客户端连接
12 conn,addr = sk.accept()
13 # 接收
14 data = conn.recv(1024)
15 print(‘.....‘,str(data,‘utf8‘))
16 # 发送
17 conn.send(bytes(‘Gun!!‘,‘utf8‘))
18 # 关闭通道
19 sk.close()

服务端

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 连接到指定服务器端口
 7 sk.connect(address)
 8 # 发送
 9 sk.send(bytes(‘Hello!!‘,‘utf8‘))
10 # 接收
11 data = sk.recv(1024) # 阻塞
12 print(str(data,‘utf8‘))
13 # 关闭通道
14 sk.close()

客户端

2、实例二:客户端不间断发送消息,但服务端没有回应,客户端也没辙

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 为socket绑定IP和端口号
 7 sk.bind(address)
 8 # 监听端口等待客户端的请求
 9 sk.listen(3)  # 3代表排队的人数
10 print(‘waiting.....‘)
11 # accept阻塞,等待客户端连接
12 conn,addr = sk.accept()
13 while True:
14     # 接收
15     data = conn.recv(1024)
16     print(‘.....‘,str(data,‘utf8‘))
17     # 服务端接收到ByeBye也结束聊天
18     if str(data,‘utf8‘) == ‘ByeBye‘:
19         break
20     # 发送
21     inp = input(‘>>>‘)
22     conn.send(bytes(inp,‘utf8‘))
23 # 关闭通道
24 sk.close()

服务端

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 连接到指定服务器端口
 7 sk.connect(address)
 8 while True:
 9 # 发送
10     inp = input(‘>>>‘)
11     sk.send(bytes(inp,‘utf8‘))
12     # 客户端输入ByeBye则结束聊天
13     if inp == ‘ByeBye‘:
14         break
15     # 接收
16     data = sk.recv(1024) # 阻塞
17     print(str(data,‘utf8‘))
18 # 关闭通道
19 sk.close()

客户端

3、实例三:服务端可以和多个客户端发送消息(虽然不是并发)

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 为socket绑定IP和端口号
 7 sk.bind(address)
 8 # 监听端口等待客户端的请求
 9 sk.listen(3)  # 3代表排队的人数
10 print(‘waiting.....‘)
11
12 while True:
13 # accept阻塞,等待客户端连接
14     conn,addr = sk.accept()
15     print(addr)
16
17     while True:
18         try:
19         # 接收
20             data = conn.recv(1024)
21             print(‘.....‘,str(data,‘utf8‘))
22         except Exception as e:
23             print(e)
24             break
25         if not data:
26             break
27         # 发送
28         inp = input(‘>>>‘)
29         conn.send(bytes(inp,‘utf8‘))
30
31 # 关闭通道
32 sk.close()

服务端

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 连接到指定服务器端口
 7 sk.connect(address)
 8 while True:
 9 # 发送
10     inp = input(‘>>>‘)
11     sk.send(bytes(inp,‘utf8‘))
12     # 客户端输入ByeBye则结束聊天
13     if inp == ‘ByeBye‘:
14         break
15     # 接收
16     data = sk.recv(1024) # 阻塞
17     print(str(data,‘utf8‘))
18 # 关闭通道
19 sk.close()

客户端

4、实例四:并发聊天(服务端需要用到socketserver模块)

A:简单并发实例

 1 import socketserver
 2
 3 class MyServer(socketserver.BaseRequestHandler):
 4
 5     def handle(self):
 6         print ("服务端启动...")
 7         while True:
 8             conn = self.request
 9             print (self.client_address)
10             while True:
11                 client_data=conn.recv(1024)
12                 print (str(client_data,"utf8"))
13                 print ("waiting...")
14                 conn.sendall(client_data)
15             conn.close()
16
17 if __name__ == ‘__main__‘:
18     server = socketserver.ThreadingTCPServer((‘127.0.0.1‘,8888),MyServer)
19     server.serve_forever()

服务端

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5
 6 address = (‘127.0.0.1‘,8888)
 7 # 连接到指定服务器端口
 8 sk.connect(address)
 9 print(‘客户端启动...‘)
10 while True:
11     # 发送
12     inp = input(‘>>>‘)
13     sk.send(bytes(inp,‘utf8‘))
14     if inp == ‘exit‘:
15         break
16     # 接收
17     data = sk.recv(1024) # 阻塞
18     print(str(data,‘utf8‘))
19
20 # 关闭通道
21 sk.close()

客户端

B:并发聊天实例

 1 class MyServer(socketserver.BaseRequestHandler):
 2
 3     def handle(self):
 4         print ("服务端启动...")
 5         while True:
 6             conn = self.request
 7             print (self.client_address)
 8             while True:
 9
10                 client_data=conn.recv(1024)
11
12                 print (str(client_data,"utf8"))
13                 print ("waiting...")
14                 server_response=input(">>>")
15                 conn.sendall(bytes(server_response,"utf8"))
16
17             conn.close()
18
19 if __name__ == ‘__main__‘:
20     server = socketserver.ThreadingTCPServer((‘127.0.0.1‘,8888),MyServer)
21     server.serve_forever()

服务端

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5
 6 address = (‘127.0.0.1‘,8888)
 7 # 连接到指定服务器端口
 8 sk.connect(address)
 9 print(‘客户端启动...‘)
10 while True:
11     # 发送
12     inp = input(‘>>>‘)
13     sk.send(bytes(inp,‘utf8‘))
14     if inp == ‘exit‘:
15         break
16     # 接收
17     data = sk.recv(1024) # 阻塞
18     print(str(data,‘utf8‘))
19
20 # 关闭通道
21 sk.close()

客户端

五、其他应用

1、远程执行命令

 1 import socket,subprocess
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 为socket绑定IP和端口号
 7 sk.bind(address)
 8 # 监听端口等待客户端的请求
 9 sk.listen(3)  # 3代表排队的人数
10 print(‘waiting.....‘)
11
12 while True:
13 # accept阻塞,等待客户端连接
14     conn,addr = sk.accept()
15     print(addr)
16
17     while True:
18         try:
19         # 接收
20             data = conn.recv(1024)
21         except Exception as e:
22             print(e)
23             break
24         if not data:
25             break
26         print(‘.....‘, str(data, ‘utf8‘))
27         # 执行命令
28         obj = subprocess.Popen(str(data,‘utf8‘),shell=True,stdout=subprocess.PIPE)
29         # 获取命令返回结果
30         cmd_result = obj.stdout.read()
31         # 获取命令返回结果的长度
32         result_len = bytes(str(len(cmd_result)),‘utf8‘)
33         print(‘>>>>>‘,result_len)
34         # 发送命令返回结果的长度
35         conn.send(result_len)  # 两次发送容易造成粘包现象:会把第二次发送的部分内容和第一次发送的内容一起发送
36         # 解决粘包现象需要在两次发送中间加一个conn.recv,需要在clint端对应一个sk.send(‘ok‘)
37         conn.recv(1024)
38         # 发送命令返回结果
39         conn.send(cmd_result)
40
41 # 关闭通道
42 sk.close()

服务端

 1 import socket
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5
 6 address = (‘127.0.0.1‘,8888)
 7 # 连接到指定服务器端口
 8 sk.connect(address)
 9
10 while True:
11     # 发送
12     inp = input(‘>>>‘)
13     if inp == ‘exit‘:
14         break
15     sk.send(bytes(inp,‘utf8‘))
16
17     # 接收返回结果的长度
18     result_len = int(str(sk.recv(1024),‘utf8‘))
19     print(result_len)
20     # 对应server端解决粘包现象的conn.recv(1024)
21     sk.send(bytes(‘ok‘,‘utf8‘))
22     # 循环接收返回结果
23     data = bytes()
24     while len(data) != result_len:
25         res = sk.recv(1024) # 阻塞
26         data = data + res
27     # windows执行的命令是按gbk格式编码的,所以这里要用gbk解码
28     print(str(data,‘gbk‘))
29
30 # 关闭通道
31 sk.close()

客户端

注意:

  • 两次发送容易造成粘包现象:会把第二次发送的部分内容和第一次发送的内容一起发送。解决粘包现象需要在两次发送中间加一个conn.recv,需要在clint端对应一个sk.send();
  • 客户端将所有的数据都放到缓冲区,每次recv多少字节取决于recv内的参数,理论不应该超过8k。所以,并不能一次recv()无限大数据,所以这里我们通过循环去接收;

2、文件上传

 1 import socket,os
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5 address = (‘127.0.0.1‘,8888)
 6 # 为socket绑定IP和端口号
 7 sk.bind(address)
 8 # 监听端口等待客户端的请求
 9 sk.listen(3)  # 3代表排队的人数
10 print(‘waiting.....‘)
11 # 设定主目录BASE_DIR
12 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
13
14 while True:
15 # accept阻塞,等待客户端连接
16     conn,addr = sk.accept()
17     print(addr)
18
19     while True:
20         # 接收客户端发送的文件信息
21         data = conn.recv(1024)
22         # 命令,文件名,文件大小,从文件信息中获取
23         cmd,file_name,file_size = str(data,‘utf8‘).split(‘|‘)
24         # 上传到服务器的路径
25         path = os.path.join(BASE_DIR,‘yuan‘,file_name)
26         # 将文件大小转换成数字类型
27         file_size = int(file_size)
28         # 在目标路径下创建文件
29         f = open(path,‘ab‘) # 以bytes类型写
30         has_received = 0    # 已接收内容大小
31         # 循环接收写入文件
32         while has_received != file_size:
33             data = conn.recv(1024)
34             f.write(data)
35             has_received += len(data)
36         f.close()
37
38 # 关闭通道
39 sk.close()

服务端

 1 import socket,os
 2 # 创建socket
 3 sk = socket.socket()
 4 print(sk)
 5
 6 address = (‘127.0.0.1‘,8888)
 7 # 连接到指定服务器端口
 8 sk.connect(address)
 9
10 # 设定主目录BASE_DIR
11 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
12
13 while True:
14     # 输入命令,命令格式:post|0170.JPG
15     inp = input(‘>>>‘).strip()
16     # 获取命令和路径
17     cmd,path = inp.split(‘|‘)
18     # 获取文件的全路径
19     path = os.path.join(BASE_DIR,path)
20     # 获取文件名
21     file_name = os.path.basename(path)
22     # 获取文件大小
23     file_size = os.stat(path).st_size
24     # 生成文件信息,格式:命令|文件名|文件大小
25     file_info = ‘post|%s|%s‘%(file_name,file_size)
26     # 发送
27     sk.send(bytes(file_info,‘utf8‘))
28     # 打开文件
29     f = open(path,‘rb‘) # 以bytes类型读
30     has_sent = 0  # 已发送内容大小
31     # 循环读取文件发送,每次1024个字节
32     while has_sent != file_size:
33         data = f.read(1024) # 每次发送1024字节
34         sk.send(data)
35         has_sent += len(data)
36     f.close()
37     print(‘上传成功!‘)
38
39 # 关闭通道
40 sk.close()

客户端

注意:

  • 一发一收,循环发送和接收。客户端发送1024字节,服务端接收1024字节;
  • 服务端data = conn.recv(1024),如果客户端发送一个空数据,则recv继续阻塞,等待其他的数据。

六、SocketServer模块

  虽说用Python编写简单的网络程序很方便,但复杂一点的网络程序还是用现成的框架比较好。这样我们就可以专心事务逻辑,而不是套接字的各种细节。SocketServer模块简化了编写网络服务程序的任务。同时SocketServer模块也是Python标准库中很多服务器框架的基础。

  SocketServer模块可以简化网络服务器的编写,Python把网络服务抽象成两个主要的类,一个是Server类,用于处理连接相关的网络操作,另外一个则是RequestHandler类,用于处理数据相关的操作。并且提供两个MixIn类,用于扩展Server,实现多进程或多线程。

1、Server类

  SocketServer模块包含了种五个server类,BaseServer(不直接对外服务),TCPServer使用TCP协议,UDPServer使用UDP协议,还有两个不常使用的,即UnixStreamServer和UnixDatagramServer,这两个类仅仅在unix环境下有用(AF_unix)。

BaseServer

  • Base class for server classes
  • class BaseServer

TCPServer

  • This uses the Internet TCP protocol, which provides for continuous streams of data between the client and server
  • class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)

UDPServer

  • This uses datagrams, which are discrete packets of information that may arrive out of order or be lost while in transit. The parameters are the same as for TCPServer
  • class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)

UnixStreamServer

UnixDatagramServer

  • These more infrequently used classes are similar to the TCP and UDP classes, but use Unix domain sockets; they‘re not available on non-Unix platforms. The parameters are the same as for TCPServer
  • class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
  • class socketserver.UnixDatagramServer(server_address, RequestHandlerClass,bind_and_activate=True)
  • 1 class UnixStreamServer(TCPServer):
    2     address_family = socket.AF_UNIX
    3
    4 class UnixDatagramServer(UDPServer):
    5     address_family = socket.AF_UNIX

There are five classes in an inheritance diagram, four of which represent synchronous servers of four types:

2、RequestHandler类

所有requestHandler都继承BaseRequestHandler基类

创建一个SocketServer至少分以下几步:

  1. First, you must create a request handler class by subclassing the BaseRequestHandlerclass and overriding its handle() method; this method will process incoming requests.
  2. Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.
  3. Then call the handle_request() orserve_forever() method of the server object to process one or many requests.
  4. Finally, call server_close() to close the socket.

想让SocketServer并发起来,必须选择使用以下一个多并发的类:

  1. class socketserver.ForkingTCPServer
  2. class socketserver.ForkingUDPServer
  3. class socketserver.ThreadingTCPServer
  4. class socketserver.ThreadingUDPServer

所以:

1 server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
2 #替换为
3 server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)

原文地址:https://www.cnblogs.com/L-Test/p/10352856.html

时间: 2024-10-25 07:03:43

Python学习之==>Socket网络编程的相关文章

Linux程序设计学习笔记----Socket网络编程基础之TCP/IP协议簇

转载请注明出处: ,谢谢! 内容提要 本节主要学习网络通信基础,主要涉及的内容是: TCP/IP协议簇基础:两个模型 IPv4协议基础:IP地址分类与表示,子网掩码等 IP地址转换:点分十进制\二进制 TCP/IP协议簇基础 OSI模型 我们知道计算机网络之中,有各种各样的设备,那么如何实现这些设备的通信呢? 显然是通过标准的通讯协议,但是,整个网络连接的过程相当复杂,包括硬件.软件数据封包与应用程序的互相链接等等,如果想要写一支将联网全部功能都串连在一块的程序,那么当某个小环节出现问题时,整只

python进阶之Socket 网络编程

 一:网络编程介绍   自从互联网诞生以来,现在基本上所有的程序都是网络程序,很少有单机版的程序了. 计算机网络就是把各个计算机连接到一起,让网络中的计算机可以互相通信.网络编程就是如何在程序中实现两台计算机的通信. 举个例子,当你使用浏览器访问新浪网时,你的计算机就和新浪的某台服务器通过互联网连接起来了,然后,新浪的服务器把网页内容作为数据通过互联网传输到你的电脑上. 由于你的电脑上可能不止浏览器,还有QQ.Skype.Dropbox.邮件客户端等,不同的程序连接的别的计算机也会不同,所以,更

python学习笔记11 ----网络编程

网络编程 网络编程需要知道的概念 1.网络体系结构就是使用这些用不同媒介连接起来的不同设备和网络系统在不同的应用环境下实现互操作性,并满足各种业务需求的一种粘合剂.网络体系结构解决互质性问题彩是分层方法. 网络(OSI)的7层模型: 应用层--->为应用程序提供网络通信服务 表示层--->数据表示 会话层--->主机间通信(两个应用进程间) 传输层--->端到端的连接,隔离网络的上下层协议,使得网络应用与下层协议无关 网络层--->寻找最优路径,转发数据包 数据链路层---&

《Python学习之路 -- 网络编程》

在前面已经提到过,互联网的本质就是一堆协议,协议就是标准,比如全世界人通信的标准是英语,所有的计算机都学会了互联网协议,那么所有的计算机就可以按照统一的标准去收发信息完成通信了. 作为普通开发人员的我们,写的软件/程序都是处于应用层上的,然而,想要让软件接入互联网,就必须得通过传输层,也就是必须遵循TCP协议或者UDP协议.这是两个非常复杂的协议,如果遵循原生的协议,那么必然会大大降低效率,所以就有了socket抽象层的概念.socket是应用层与TCP/IP协议族通信的软件抽象层,它是一组接口

python自动化开发学习-9 socket网络编程

一. 简介 python提供了两个级别访问的网络服务: 低级别的网络服务支持节本的socket,它提供了标准的BSD sockets API,可以访问底层操作系统socket接口的全部方法. 高级别的网络服务模块socketserver,它提供了服务器中心类,可以简化网络服务器的开发. socket介绍 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Unix

Python基础12 - Socket网络编程

一.计算机网络 网络通信要素: 1.IP地址:A.用来标识网络上一台独立的主机 B.IP地址 = 网络地址 + 主机地址(网络号:用于识别主机所在的网络/网段.主机号:用于识别该网络中的主机) C.特殊的IP地址:127.0.0.1(本地回环地址.保留地址,点分十进制)可用于简单的测试网卡是否故障.表示本机. 2.端口号:A.用于标识进程的逻辑地址.不同的进程都有不同的端口标识. B.端口:要将数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识.为了方便

c#学习之Socket网络编程

我是新手以前没写过博客 希望大家勿喷, 在编写Socket的时候需要导入System.Net.Socket 命名空间.利用该类我们可以直接编写Socket的客户端和服务的的程序了, 这里我们只讲tpc协议下的Socket编程. TCP Socket连接的过程可以简单的分为:①.服务端监听 ②.客户端请求 ③.建立连接, 在服务端: (1)声明一个套接字(称为监听套接字)Socket serverSocket = new Socket(AddressFamily.InterNetwork, Soc

Python学习笔记之网络编程

操作MySQL # 断言 assert(1==1) ############################################################################# ******************************************************************** # 创建Connection * ------------------------------------------------------------

python资源库之socket网络编程

sockket简介 socekt又称为'套接字',用于描述IP和地址端口,是一个通信链路的句柄,应用程序通常通过套接字向网络发出请求或者应答网络请求. socket起源于Unix,所以也遵从"一切皆文件"的基本哲学,对于文件,进行打开/读取/关闭的操作模式.socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO.打开.关闭). socket和file文件的区别: file模块是针对指定文件进行打开.读写.关闭操作. sock