溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

socket&socket實(shí)現(xiàn)ftp的get方法、socke

發(fā)布時(shí)間:2020-06-25 04:44:40 來源:網(wǎng)絡(luò) 閱讀:909 作者:1350368559 欄目:建站服務(wù)器

首先了解socket工作原理,client-server模式


1、socket客戶端:

2、socket類型

3、socket數(shù)據(jù)流

4、實(shí)驗(yàn)

(1)寫一個(gè)client

服務(wù)端啟動(dòng)監(jiān)聽ip和端口

admindeMacBook-Air-62:~ admin$ nc -l 1234

客戶端連接服務(wù)端,發(fā)數(shù)據(jù),關(guān)閉socket

pycharm中添加一個(gè)socket_client.py并之行:

import socket
HOST = '127.0.0.1'
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
s.sendall('hello world')
s.close()

服務(wù)端退出socket

admindeMacBook-Air-62:~ admin$ nc -l 1234
hello world
admindeMacBook-Air-62:~ admin$

客戶端發(fā)送10次

socket_client10.py

#-*-coding: UTF-8 -*-
#coding=utf-8
import socket
import time
HOST = '127.0.0.1'
PORT = 1234
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #元祖(網(wǎng)絡(luò)socket,tcp) 
s.connect((HOST,PORT))
for i in range(10):
    s.sendall('%s  hello, world\n' %i)
    time.sleep(1)
s.close()

服務(wù)端打印10次退出

admindeMacBook-Air-62:~ admin$ nc -l 1234
0  hello, world
1  hello, world
2  hello, world
3  hello, world
4  hello, world
5  hello, world
6  hello, world
7  hello, world
8  hello, world
9  hello, world
admindeMacBook-Air-62:~ admin$

(2)寫一個(gè)server

socket_server01.py

#coding=UTF-8
import socket
import time
HOST = '' #表示監(jiān)聽0.0.0.0
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #網(wǎng)絡(luò),tcp
s.bind((HOST,PORT))
s.listen(1)    #一次接受一個(gè),寫2也是一次接受一個(gè)
connect, address = s.accept()  #接受客戶端的請求,返回的是一個(gè)連結(jié)句柄connect+地址
print 'connent',connect
print 'Connected by', address
while 1:
    data = connect.recv(1024)
    if not data: break
    connect.sendall(data.upper())
connect.close()
admindeMacBook-Air-62:host_performance-monitor admin$ python socket_server01.py

啟動(dòng)程序并查看端口

admindeMacBook-Air-62:~ admin$ netstat -an | grep 1234
tcp4       0      0  *.1234                 *.*                    LISTEN

客戶端:

socket-client for server.py

#-*-coding: UTF-8 -*-
#coding=utf-8
import socket
import time
HOST = '127.0.0.1'
PORT = 1234
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #網(wǎng)絡(luò)socket,tcp
s.connect((HOST,PORT))
s.sendall('hello, world') #客戶端發(fā)送1024字節(jié)
data = s.recv(1024) #接受服務(wù)器發(fā)送過來的數(shù)據(jù)
s.close()
print  'Received', repr(data) #打印服務(wù)端發(fā)送過來的數(shù)據(jù)
print data


客戶端之行發(fā)送hello world,接受HELLO WORLD

python socket-client for server.py
Received 'HELLO, WORLD'
HELLO, WORLD
admindeMacBook-Air-62:host_performance-monitor admin$ python socket_server01.py
connent <socket._socketobject object at 0x10427ec20>
Connected by ('127.0.0.1', 63878)

現(xiàn)在讓客戶端一直發(fā),服務(wù)端一直接受數(shù)據(jù),一端關(guān)閉socket連接,另一端也自動(dòng)關(guān)閉連接

server端代碼基本上不變

socket_server01.py

#coding=UTF-8
import socket
import time
HOST = '' #表示監(jiān)聽0.0.0.0
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #網(wǎng)絡(luò),tcp
s.bind((HOST,PORT))
s.listen(1)    #一次接受一個(gè),寫2也是一次接受一個(gè)
connect, address = s.accept()  #接受客戶端的請求,返回的是一個(gè)連結(jié)句柄connect+地址
print 'connent',connect
print 'Connected by', address
while 1:
    data = connect.recv(1024)
    print data
    if not data: break
    connect.sendall(data.upper())
connect.close()


啟動(dòng)server,并查看端口:

admindeMacBook-Air-62:host_performance-monitor admin$ python socket_server01.py
admindeMacBook-Air-62:~ admin$ netstat -an | grep 1234
tcp4       0      0  *.1234                 *.*                    LISTEN

client端代碼:

vim clinet_not_stop.py
#-*-coding: UTF-8 -*-
#coding=utf-8
import socket
import time
HOST = '127.0.0.1'
PORT = 1234
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #網(wǎng)絡(luò)socket,tcp
s.connect((HOST,PORT))
while True:
s.sendall('hello, world') #客戶端發(fā)送1024字節(jié)
data = s.recv(1024) #接受服務(wù)器發(fā)送過來的數(shù)據(jù)
print data
time.sleep(1)
s.close()
admindeMacBook-Air-62:host_performance-monitor admin$ python  python clinet_not_stop.py  client接受到server大寫返回
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD

同時(shí)可以看到server端的來自client的發(fā)送數(shù)據(jù),全部小寫的hello world

admindeMacBook-Air-62:host_performance-monitor admin$ python socket_server01.py
connent <socket._socketobject object at 0x10baedc20>
Connected by ('127.0.0.1', 64589)
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world

按ctrl+c終止傳輸


新的需求,客戶端發(fā)送命令,服務(wù)端接收命令并之行,并返回結(jié)果,客戶端使用exit或者quit,退出。

server:socket_server_command.py

#-*-coding: UTF-8 -*-
#coding=UTF-8
import socket
from subprocess import Popen,PIPE
HOST = '' #表示監(jiān)聽0.0.0.0
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #網(wǎng)絡(luò),tcp
s.bind((HOST,PORT))
s.listen(1)    #一次接受一個(gè),寫2也是一次接受一個(gè)
connect, address = s.accept()  #接受客戶端的請求,返回的是一個(gè)連結(jié)句柄connect+地址
print 'connent',connect
print 'Connected by', address
while 1:
    cmd = connect.recv(1024)
    p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
    stdout = p.stdout.read()
    stderr = p.stderr.read()
    if stdout:
        connect.sendall(stdout)
    if stderr:
        connect.sendall(stderr)
    if not cmd: break
connect.close()


client:socket_clinet_command.py

#-*-coding: UTF-8 -*-
#coding=utf-8
import socket
import time
import tab #參考:http://daixuan.blog.51cto.com/5426657/1934112
HOST = '127.0.0.1'
PORT = 1234
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #網(wǎng)絡(luò)socket,tcp
s.connect((HOST,PORT))
while True:
    cmd = raw_input("Please input cmd:").strip() #把空字符串命令去掉,做一個(gè)判斷,非空再發(fā)送
    if cmd.lower() == 'exit' or cmd.lower() == 'quit':
        break
    if cmd:
        s.sendall(cmd) #客戶端發(fā)送命令
        data = s.recv(1024) #接受服務(wù)器發(fā)送過來的數(shù)據(jù)
        print data
s.close()


server啟動(dòng)服務(wù):(有客戶端連接會(huì)顯示連接句柄)

admindeMacBook-Air-62:host_performance-monitor admin$ python socket_server_command.py
connent <socket._socketobject object at 0x109192de0>
Connected by ('127.0.0.1', 65512)

客戶端啟動(dòng)并之行命令:

admindeMacBook-Air-62:host_performance-monitor admin$ python socket_clinet_command.py
Please input cmd:date
2017年 6月10日 星期六 18時(shí)34分21秒 CST
Please input cmd:pwd
/Users/admin/Desktop/project/host_performance-monitor
Please input cmd:exit


5、實(shí)現(xiàn)FTP下載功能:

1、get source dest

2、重復(fù)文件,加.new

3、打印出來get下來的文件名是/tmp/hosts 還是/tmp/hosts.new

服務(wù)端:socket_server_ftp.py

#-*-coding: UTF-8 -*-
#coding=UTF-8
import socket
from subprocess import Popen,PIPE
HOST = '' #表示監(jiān)聽0.0.0.0
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #網(wǎng)絡(luò),tcp
s.bind((HOST,PORT))
s.listen(1)    #一次接受一個(gè),寫2也是一次接受一個(gè)
connect, address = s.accept()  #接受客戶端的請求,返回的是一個(gè)連結(jié)句柄connect+地址
print 'connent',connect
print 'Connected by', address
while 1:
    cmd = connect.recv(1024)
    cmd_list = cmd.split()
    if cmd_list[0] == 'get':   #如果是get方法,讀數(shù)據(jù)
        with open(cmd_list[1]) as fd:
            while True:   #循環(huán)讀取1024字節(jié),然后返回一個(gè)數(shù)
                data = fd.read(1024)
                connect.sendall(data)
                if not data:   #數(shù)據(jù)讀完了,跳出while循環(huán)
                    connect.sendall('EOF')
                    break
    if not cmd: break
connect.close()


客戶端:socket_clinet_ftp.py

#-*-coding: UTF-8 -*-
#coding=utf-8
import socket
import time
import tab  #參考:http://daixuan.blog.51cto.com/5426657/1934112
import os
HOST = '127.0.0.1'
PORT = 1234
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #網(wǎng)絡(luò)socket,tcp
s.connect((HOST,PORT))
while True:
   cmd = raw_input("Please input cmd:").strip() #把空字符串命令去掉,做一個(gè)判斷,非空再發(fā)送
   if cmd.lower() == 'exit' or cmd.lower() == 'quit':
       break
   cmd_list = cmd.split()
   if len(cmd_list) != 3:
       print "Ex: get file1 file2"
       continue
   else:
       s.sendall(cmd) #客戶端發(fā)送命令
       if not os.path.exists(cmd_list[2]):
           dst_file = cmd_list[2]
       else:
           dst_file = cmd_list[2]+'.new'
       n = 1   #定義一個(gè)變量,第一次打開文件是wb方式,第二次打開文件是a(追加)的方式打開。
       while True:
           data_rev = s.recv(1024)  # 接受服務(wù)器發(fā)送過來的數(shù)據(jù),但是服務(wù)器發(fā)送完數(shù)據(jù),客戶端仍在等待,就會(huì)卡住。用EOF,就break
           if data_rev.endswith('EOF'):
               data = data_rev[:-3]
           else:
               data = data_rev
           if n == 1:
               with open(dst_file, 'wb')  as fd:
                   fd.write(data)
           else:
               with open(dst_file, 'a') as fd:
                   fd.write(data)
                   print data
           n +=1
           print "destination file is %s" %dst_file
           if data_rev[-3:] == 'EOF':  #如果最后三個(gè)字符是EOF,退出ftp
               break
s.close()


啟動(dòng)服務(wù)端:

admindeMacBook-Air-62:host_performance-monitor admin$ python socket_server_ftp.py
connent <socket._socketobject object at 0x104ecbde0>
Connected by ('127.0.0.1', 53858)

啟動(dòng)客戶端:

admindeMacBook-Air-62:host_performance-monitor admin$ python socket_clinet_ftp.py
Please input cmd:get /etc/hosts /tmp/hosts
destination file is /tmp/hosts
Please input cmd:get /etc/hosts /tmp/hosts
destination file is /tmp/hosts.new


6、SocketServer

socketserver是一個(gè)類,自帶多線程

編寫一個(gè)hander類,繼承BaseRequestHander,重寫handle()方法

針對tcp還是udp生成一個(gè)server對象

調(diào)用server對象的handle_request或者sever_forver方法

(1)socket server官方的例子,一個(gè)腳本中服務(wù)端核客戶端

https://docs.python.org/2.7/library/socketserver.html?highlight=socketserver

vim socket-threading-thread.py
import socket
import threading
import SocketServer
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        cur_thread = threading.current_thread()
        response = "%s %s" % (cur_thread.name, data)
        self.request.sendall(response)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
   pass
def client(ip, port, message):
   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   sock.connect((ip, port))
   try:
       sock.sendall(message)
       response = sock.recv(1024)
       print response
   finally:
       sock.close()
if __name__ == "__main__":
   # Port 0 means to select an arbitrary unused port
   HOST, PORT = "localhost", 0
   server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
   ip, port = server.server_address
   # Start a thread with the server -- that thread will then start one
   # more thread for each request
   server_thread = threading.Thread(target=server.serve_forever)
   # Exit the server thread when the main thread terminates
   server_thread.daemon = True
   server_thread.start()
   print "Server loop running in thread:", server_thread.name
   client(ip, port, "Hello World 1")
   client(ip, port, "Hello World 2")
   client(ip, port, "Hello World 3")
   server.shutdown()
   server.server_close()
admindeMacBook-Air-62:host_performance-monitor admin$ python socket-threading-thread.py
Server loop running in thread: Thread-1
Thread-2 Hello World 1
Thread-3 Hello World 2
Thread-4 Hello World 3

(2)多個(gè)客戶端同時(shí)連接一個(gè)服務(wù)器

服務(wù)器不退出

任何一個(gè)客戶端都會(huì)有返回的結(jié)果

服務(wù)端代碼:

vim socket_clinet_command.py
#-*-coding: UTF-8 -*-
#coding=UTF-8
import socket
import threading
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        while True:
            self.data = self.request.recv(1024).strip()
            print self.client_address[0]
            print self.data
            self.request.sendall(self.data.upper())
            if not self.data:
                break

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass


if __name__ == "__main__":
    # Port 0 means to select an arbitrary unused port
    #HOST, PORT = "localhost", 9999
    HOST = 'localhost'
    PORT = 9999


    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.daemon = True
    server_thread.start()
    print "Server loop running in thread:", server_thread.name
    ##主要進(jìn)程不退出
    server.serve_forever()

客戶端代碼:

socketserver_clinet.py
#-*-coding: UTF-8 -*-
#coding=utf-8
import socket
import time
import tab  #參考:http://daixuan.blog.51cto.com/5426657/1934112
import os
HOST = 'localhost'
PORT = 9999
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT))
while True:
    s.sendall('hello, world')
    data = s.recv(1024)
    print data
    time.sleep(1)
s.close()


啟動(dòng)服務(wù)端

Server loop running in thread: Thread-1
127.0.0.1
hello, world
127.0.0.1
hello, world
127.0.0.1
hello, world
127.0.0.1
hello, world

分別啟動(dòng)兩個(gè)客戶端:

返回結(jié)果都是大寫helloworld,且相互不影響。

HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD
HELLO, WORLD


(3)使用socketserver的threading多線程實(shí)現(xiàn)ftp功能(多客戶端)

服務(wù)器端代碼:

#-*-coding: UTF-8 -*-
#coding=UTF-8
import socket
import threading
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        while True:
            self.cmd = self.request.recv(1024).strip()
            self.cmd_list = self.cmd.split()
            if self.cmd_list[0] == 'get':  # 如果是get方法,讀數(shù)據(jù)
                with open(self.cmd_list[1]) as fd:
                    while True:  # 循環(huán)讀取1024字節(jié),然后返回一個(gè)數(shù)
                        self.data = fd.read(1024)
                        self.request.sendall(self.data)
                        if not self.data:  # 數(shù)據(jù)讀完了,跳出while循環(huán)
                            self.request.sendall('EOF')
                            break
            if not self.cmd:
                break

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass


if __name__ == "__main__":
    # Port 0 means to select an arbitrary unused port
    #HOST, PORT = "localhost", 9999
    HOST = ''
    PORT = 12345


    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.daemon = True
    server_thread.start()
    print "Server loop running in thread:", server_thread.name
    ##主要進(jìn)程不退出
    server.serve_forever()

啟動(dòng)服務(wù)端監(jiān)聽端口:

/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/admin/Desktop/project/host_performance-monitor/socket-threading-thread-server-ftp.py
Server loop running in thread: Thread-1


客戶端代碼:

socket_clinet_ftp.py

#-*-coding: UTF-8 -*-
#coding=utf-8
import socket
import time
import tab  #參考:http://daixuan.blog.51cto.com/5426657/1934112
import os

HOST = '127.0.0.1'
PORT = 12345
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #網(wǎng)絡(luò)socket,tcp
s.connect((HOST,PORT))
while True:
    cmd = raw_input("Please input cmd:").strip() #把空字符串命令去掉,做一個(gè)判斷,非空再發(fā)送
    if cmd.lower() == 'exit' or cmd.lower() == 'quit':
        break
    cmd_list = cmd.split()
    if len(cmd_list) != 3:
        print "Ex: get file1 file2"
        continue
    else:
        s.sendall(cmd) #客戶端發(fā)送命令
        if not os.path.exists(cmd_list[2]):
            dst_file = cmd_list[2]
        else:
            dst_file = cmd_list[2]+'.new'
        n = 1   #定義一個(gè)變量,第一次打開文件是wb方式,第二次打開文件是a(追加)的方式打開。
        while True:
            data_rev = s.recv(1024)  # 接受服務(wù)器發(fā)送過來的數(shù)據(jù),但是服務(wù)器發(fā)送完數(shù)據(jù),客戶端仍在等待,就會(huì)卡住。用EOF,就break
            if data_rev.endswith('EOF'):
                data = data_rev[:-3]
            else:
                data = data_rev
            if n == 1:
                with open(dst_file, 'wb')  as fd:
                    fd.write(data)
            else:
                with open(dst_file, 'a') as fd:
                    fd.write(data)
                    print data
            n +=1
            print "destination file is %s" %dst_file
            if data_rev[-3:] == 'EOF':  #如果最后三個(gè)字符是EOF,退出ftp
                break
s.close()

分別啟動(dòng)兩個(gè)客戶端,可以同時(shí)使用get方法,斷開其中一個(gè)客戶端對服務(wù)端無影響。

客戶端1:
/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/admin/Desktop/project/host_performance-monitor/socket_clinet_ftp.py
Please input cmd:ls
Ex: get file1 file2
Please input cmd:get /tmp/1.txt /tmp/2.txt
destination file is /tmp/2.txt
Please input cmd:

客戶端2:
/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/admin/Desktop/project/host_performance-monitor/socket_clinet_ftp.py
Please input cmd:get /tmp/1.txt /tmp/2.txt
destination file is /tmp/2.txt.new
destination file is /tmp/2.txt.new
Please input cmd:
Ex: get file1 file2
Please input cmd:get /tmp/1.txt /tmp/2.txt
destination file is /tmp/2.txt.new
destination file is /tmp/2.txt.new
Please input cmd:


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI