python~socket编程学习总结(二)

简单模拟和服务器通信的客户端

未加异常版本(对服务端进行死循环处理)

服务端程序

#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.sendsocket.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()

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值