简单模拟和服务器通信的客户端
未加异常版本(对服务端进行死循环处理)
服务端程序
#encoding=utf-8
import socket
HOST='127.0.0.1'
PORT=8095
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义socket类型,网络通信,TCP
s.bind((HOST,PORT)) #套接字绑定的IP与端口
s.listen(1) #开始TCP监听,listen中的参数表示可以多少客户端来进行连接
while True:
print("开始连接")
conn,addr=s.accept() #接受TCP连接,并返回新的套接字与IP地址
print('Connected by',addr) #输出客户端的IP地址
while True:
data=conn.recv(1024) #把接收的数据实例化
if data.decode("utf-8").strip() == "bye":
break
print(data.decode("utf-8"))
conn.sendall('从服务得到结果:'.encode("utf-8")+data.upper())
conn.close()
客户端程序
#encoding=utf-8
import sys
import socket
HOST = '127.0.0.1'
PORT = 8095
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 定义socket类型,网络通信,TCP
s.connect((HOST, PORT)) # 要连接的IP与端口
while True:
cmd = input(u"向服务器发送命令:") # 实现交互,输入命令
s.sendall(cmd.encode("utf-8")) # 把命令发送给对端
if cmd == "bye":
break
data = s.recv(1024) # 把接收的数据定义为变量
print(data.decode("utf-8")) # 输出接收的数据
s.close() # 关闭连接
加异常版本
服务器端程序
#encoding=utf-8
import socket
HOST='127.0.0.1'
PORT=8095
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义socket类型,网络通信,TCP
s.bind((HOST,PORT)) #套接字绑定的IP与端口
s.listen(5) #开始TCP监听,listen中的参数表示可以多少客户端来进行连接
while True:
print(u"开始连接")
conn,addr=s.accept() #接受TCP连接,并返回新的套接字与IP地址
print('Connected by',addr) #输出客户端的IP地址
while True:
try:
data=conn.recv(1024) #把接收的数据实例化
print (data)
conn.sendall(u'从服务得到结果:'.encode("utf-8")+data.upper())
except Exception:
conn.close()
break
客户端程序
#encoding=utf-8
import sys
import socket
HOST = '127.0.0.1'
PORT = 8095
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 定义socket类型,网络通信,TCP
s.connect((HOST, PORT)) # 要连接的IP与端口
times=5
while times>0:
cmd = input(u"向服务器发送命令:") #与人交互,输入命令,不能发送空数据
s.sendall(cmd.encode("utf-8")) #将命令发送给服务端
data = s.recv(1024) #把接收的数据定义为变量
print(data.decode("utf-8")) #输出变量
times-=1
s.close() # 关闭连接
对客户端传入数据做简单处理
服务端程序
#encoding=utf-8
import time
import socket
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8009))
sock.listen(5)
while True:
print(u"服务开始监听状态")
time.sleep(0.1)
connection,address = sock.accept()
while True:
try:
connection.settimeout(5) #设置阻塞模式下socket的超时时间
buf = connection.recv(1024).decode("utf-8")
print("got message from client:",buf )
if buf == '1':
print("1" )
connection.send('您做的操作是:选择1'.encode("utf-8"))
elif buf == '2':
connection.send('您做的操作是:选择2'.encode("utf-8"))
elif buf == "close":
connection.send('您做的操作是:选择close'.encode("utf-8"))
connection.close()
break
except socket.timeout:
print('连接超时')
connection.close()
break
except Exception as e:
print(e )
connection.close()
break
客户端程序
#encoding=utf-8
import time
import socket
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 8009))
time.sleep(2)
sock.send('2'.encode("utf-8"))
print(sock.recv(1023).decode("utf-8"))
sock.send('1'.encode("utf-8"))
print(sock.recv(1024).decode("utf-8"))
sock.send('close'.encode("utf-8"))
print(sock.recv(1024).decode("utf-8"))
print("Done!")
sock.close()
实现一个调用系统命令的功能(此例子为window)
os.system(cmd):执行命令,不保存结果,输出完了就结束
os.popen(cmd,mode='r', buffering=-1):执行命令后,将结果保存在内存,需要用read()方法取出来
服务端程序
import os
import socket
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8001))
sock.listen(5)
while True:
connection,address = sock.accept()
try:
connection.settimeout(5)
command = connection.recv(1024)
print(command)
result=os.popen(command.decode("utf-8"))
connection.send(command)
connection.send(result.read().encode("utf-8"))
except socket.timeout:
print('time out')
connection.close()
客户端程序
import socket
import time
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 8001))
time.sleep(2)
sock.send('ipconfig'.encode("utf-8"))
print("command:",sock.recv(10).decode("utf-8"))
print ("command result:",sock.recv(1024).decode("utf-8"))
sock.close()
socket.send和socket.sendall的区别
socket.send(string[, flags]) 发送TCP数据,返回发送的字节大小。这个字节长度可能少于实际要发送的数据的长度。换句话说,这个函数执行一次,并不一定能发送完给定的数据,可能需要重复多次才能发送完成。
socket.sendall(string[, flags])发送完整的TCP数据,成功返回None,失败抛出异常
使用socket传送一个文件
服务端程序
# -*- coding: UTF-8 -*-
import socket, time, socketserver, struct, os, _thread
host = '127.0.0.1'
port = 12307
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 定义socket类型
s.bind((host, port)) # 绑定需要监听的Ip和端口号,tuple格式
s.listen(1)
def conn_thread(connection, address):
while True:
try:
connection.settimeout(600)
fileinfo_size = struct.calcsize('12sl')#12s表示12个字符,l表示一个长整型数
buf = connection.recv(fileinfo_size)
if buf: # 如果不加这个if,第一个文件传输完成后会自动走到下一句,需要拿到文件大小信息才可以继续执行
filename, filesize = struct.unpack('12sl', buf)
filename_f = filename.decode("utf-8").strip('\00') # C语言中’\0’是一个ASCII码为0的字符,在python中表示占一个位置得空字符
filenewname = os.path.join('e:\\', os.path.basename(filename_f))
print(u'文件名称:%s , 文件大小: %s' % (filenewname, filesize))
recvd_size = 0 # 定义接收了的文件大小
file = open(filenewname, 'wb')
print(u"开始传输文件内容")
while not recvd_size == filesize:
if filesize - recvd_size > 1024:
rdata = connection.recv(1024)
recvd_size += len(rdata)
else:
rdata = connection.recv(filesize - recvd_size)
recvd_size = filesize
file.write(rdata)
file.close()
print('receive done')
# connection.close()
except socket.timeout:
connection.close()
while True:
print(u"开始进入监听状态")
connection, address = s.accept()
print('Connected by ', address)
# thread = threading.Thread(target=conn_thread,args=(connection,address)) #使用threading也可以
# thread.start()
_thread.start_new_thread(conn_thread, (connection, address))
s.close()
客户端程序
# -*- coding: UTF-8 -*-
import socket, os, struct
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 12307))
while True:
filepath = input('请输入要传输的文件绝对路径:\r\n')
print(type(filepath))
print(len(filepath.encode("utf-8")))
if os.path.isfile(filepath):
fhead = struct.pack('12sl', filepath.encode("utf-8"), os.stat(filepath).st_size)
print(os.stat(filepath).st_size)
s.send(fhead)
print (u'文件路径: ', filepath)
fo = open(filepath, 'rb')
while True:
filedata = fo.read(1024)
if not filedata:
break
s.send(filedata)
fo.close()
print (u'传输成功')
# s.close()