bind()
listen()
accept()
recv()
send(string)
sendall()
close()
connect()
recv()
send(string)
sendall() #传送的内容一定是bytes类型
close()
背景:从前,有个屌丝阿武,想追女神阿思,闷骚型,心想:老子就给她一次机会,不把握就算了…
###### server ######
import socket
ip_port = ('127.0.0.1',9997)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
print ('server waiting...')
conn,addr = sk.accept()
client_data = conn.recv(1024)
print (str(client_data,"utf8"))
conn.sendall(bytes('滚蛋!',encoding="utf-8"))
sk.close()
###### client ######
import socket
ip_port = ('127.0.0.1',9997)
sk = socket.socket()
sk.connect(ip_port)
sk.sendall(bytes('俺喜欢你',encoding="utf8"))
server_reply = sk.recv(1024)
print (str(server_reply,"utf8"))
背景:又有个屌丝,名叫武二,想追女神阿思,内心强大,臭不要脸,于是…
注意:固然武二脸皮够厚,但是落花有意流水无情,女神不给机会和你聊也白搭(server端也需要有while)。
###### server ######
import socket
ip_port = ('127.0.0.1',8888)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(2)
print ("服务端启动...")
conn,address = sk.accept()
while True:
client_data=conn.recv(1024)
if str(client_data,"utf8")=='exit':
break
print (str(client_data,"utf8"))
server_response=input(">>>")
conn.sendall(bytes(server_response,"utf8"))
conn.close()
###### client ######
import socket
ip_port = ('127.0.0.1',8888)
sk = socket.socket()
sk.connect(ip_port)
print ("客户端启动:")
while True:
inp = input('>>>')
sk.sendall(bytes(inp,"utf8"))
if inp == 'exit':
break
server_response=sk.recv(1024)
print (str(server_response,"utf8"))
sk.close()
背景:某天,女神孤独难耐,决定调整状态想和多人聊一聊找个合适的(虽然不是并发,但是可以在不重新开启server的前提下与多人聊天)。
###### server ######
import socket
ip_port = ('127.0.0.1',8870)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(2)
print ("服务端启动...")
while True:
conn,address = sk.accept()
print(address)
while True:
try:
client_data=conn.recv(1024)
except:
print("意外中断")
break
print (str(client_data,"utf8"))
server_response=input(">>>")
conn.sendall(bytes(server_response,"utf8"))
conn.close()
###### client ######
import socket
ip_port = ('127.0.0.1',8870)
sk = socket.socket()
sk.connect(ip_port)
print ("客户端启动:")
while True:
inp = input('>>>')
if inp == 'exit':
break
sk.sendall(bytes(inp,"utf8"))
server_response=sk.recv(1024)
print (str(server_response,"utf8"))
sk.close()
###### server ######
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print ("服务端启动...")
while True:
conn = self.request
print (self.client_address)
while True:
client_data=conn.recv(1024)
print (str(client_data,"utf8"))
print ("waiting...")
server_response=input(">>>")
conn.sendall(bytes(server_response,"utf8"))
conn.sendall(client_data)
conn.close()
#print self.request,self.client_address,self.server
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8098),MyServer) #把bind,listen都封装进去了
server.serve_forever()
###### client ######
import socket
ip_port = ('127.0.0.1',8098)
sk = socket.socket()
sk.connect(ip_port)
print ("客户端启动:")
while True:
inp = input('>>>')
sk.sendall(bytes(inp,"utf8"))
server_response=sk.recv(1024)
print (str(server_response,"utf8"))
if inp == 'exit':
break
sk.close()
粘包解决:
###### server ######
import socket
import subprocess
sk = socket.socket()
print(sk)
address = ('127.0.0.1',8000)
sk.bind(address)
sk.listen(3)
print('waiting......')
while 1:
conn, addr = sk.accept()
print(address)
while 1:
try:
data = conn.recv(1024)
except Exception:
break
if not data:break
print(str(data,'utf8'))
obj = subprocess.Popen(str(data,'utf8'),shell=True,stdout=subprocess.PIPE)
cmd_result = obj.stdout.read() #cmd_result是bytes类型,是Popen命令按照Windows下的gbk规则编码的
result_len = bytes(str(len(cmd_result)),'utf8')
print('>>>>>>',result_len)
conn.sendall(result_len) #两个send在一起时容易发生粘包现象
conn.recv(1024) #粘包解决方法:用一个recv隔开
conn.sendall(cmd_result)
sk.close()
###### client ######
import socket
sk = socket.socket()
print(sk)
address = ('127.0.0.1',8000)
sk.connect(address)
while True:
inp = input('>>>')
if inp == 'exit':
break
sk.send(bytes(inp,'utf8'))
result_len = int(str(sk.recv(1024),'utf8'))
sk.sendall(bytes('111','utf8')) #解决server端粘包现象,随便发一个什么都行
print(result_len)
data = bytes() #创建一个空的bytes数据
while len(data) != result_len:
recv = sk.recv(1024)
data += recv
print(str(data, 'gbk')) #因为传来的数据是Windows内部用gbk编码的,所以用gbk解码
sk.close()
###### server ######
import socket
import os
sk = socket.socket()
print(sk)
address = ('127.0.0.1',8000)
sk.bind(address)
sk.listen(3)
print('waiting......')
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
while 1:
conn, addr = sk.accept()
while 1:
data = conn.recv(1024)
cmd,filename,filesize = str(data,'utf8').split('|')
path = os.path.join(BASE_DIR,'joe',filename)
filesize = int(filesize)
f = open(path,'ab')
has_receive = 0
while has_receive != filesize:
data = conn.recv(1024)
f.write(data)
has_receive += len(data)
f.close()
sk.close()
###### client ######
import socket
import os
sk = socket.socket()
print(sk)
address = ('127.0.0.1',8000)
sk.connect(address)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
while True:
inp = input('>>>').strip() #post|11.jpg
cmd,path = inp.split('|')
path = os.path.join(BASE_DIR,path)
filename = os.path.basename(path)
file_size = os.stat(path).st_size
file_info = 'post|%s|%s' %(filename,file_size)
sk.sendall(bytes(file_info,'utf8'))
f = open(path,'rb')
has_sent = 0
while has_sent != file_size:
data = f.read(1024)
sk.sendall(data)
has_sent += len(data)
f.close()
print('上传成功')
sk.close()
它包含了种五种server类,BaseServer(不直接对外服务)。TCPServer使用TCP协议,UDPServer使用UDP协议,还有两个不常使用的,即UnixStreamServer和UnixDatagramServer,这两个类仅仅在unix环境下有用(AF_unix)。
==================================================================
参考文献:
https://www.cnblogs.com/yuanchenqi/articles/5692716.html
本篇涉及代码见week7 —> day26, day27.