zoukankan      html  css  js  c++  java
  • socket发送文字、图片、文件---基于python实现

    socket官方文档:https://docs.python.org/2/library/socket.html

    socket中文详细介绍:http://blog.csdn.net/rebelqsp/article/details/22109925

    查看某端口是否被占用(如6666端口):sudo netstat -nap | grep 6666 如果没有查找到6666端口则说明没有被占用(额,有点废话了~~)

    客户端

    • 创建 socket
    • 连接到远程服务器
    • 发送数据
    • 接收数据
    • 关闭 socket
    #!/usr/bin/env python
    # -*- coding=utf-8 -*-
    
    
    """
    file: client.py
    socket client
    """
    
    import socket
    import sys
    
    
    def socket_client():
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(('127.0.0.1', 6666))
        except socket.error as msg:
            print msg
            sys.exit(1)
        print s.recv(1024)
        while 1:
            data = raw_input('please input work: ')
            s.send(data)
            print s.recv(1024)
            if data == 'exit':
                break
        s.close()
    
    
    if __name__ == '__main__':
        socket_client()
    

    服务器端

    • 打开 socket
    • 绑定到特定的地址以及端口上
    • 监听连接
    • 建立连接
    • 接收/发送数据
    #!/usr/bin/env python
    # -*- coding=utf-8 -*-
    
    
    """
    file: service.py
    socket service
    """
    
    
    import socket
    import threading
    import time
    import sys
    
    
    def socket_service():
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 防止socket server重启后端口被占用(socket.error: [Errno 98] Address already in use)
            s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            s.bind(('127.0.0.1', 6666))
            s.listen(10)
        except socket.error as msg:
            print msg
            sys.exit(1)
        print 'Waiting connection...'
    
        while 1:
            conn, addr = s.accept()
            t = threading.Thread(target=deal_data, args=(conn, addr))
            t.start()
    
    def deal_data(conn, addr):
        print 'Accept new connection from {0}'.format(addr)
        conn.send('Hi, Welcome to the server!')
        while 1:
            data = conn.recv(1024)
            print '{0} client send data is {1}'.format(addr, data)
            #time.sleep(1)
            if data == 'exit' or not data:
                print '{0} connection close'.format(addr)
                conn.send('Connection closed!')
                break
            conn.send('Hello, {0}'.format(data))
        conn.close()
    
    
    if __name__ == '__main__':
        socket_service()
    

    copy以上两个脚本代码后,如果你想在本地测试,直接运行这两个脚本便是(注:先运行服务端service.py脚本),下图左边是运行服务端脚本,右边打开两个终端与服务端socket进行通信。

    socket

    一屏开多个终端是不是很屌(强烈建议安装此工具,非常方便好用)

    终端增强工具Terminator 
    sudo apt-get install terminator # Ubuntu 
    yum -y install terminator # Centos

    如果你想在两台不同机器上测试,把service.py脚本上传到服务器(假设服务器ip是:192.168.1.2),然后把client.py连接ip改为:192.168.1.2,service.py监听的ip改为:192.168.1.2,接着运行这两个脚本即可

    # client.py
    s.connect(('192.168.1.2', 6666))
    
    # service.py
    s.bind(('192.168.1.2', 6666))

    利用socket进行文件、图片等传输

    传输文件主要分以下两步:

    • 将要传输的文件的基本信息发送到接收端(文件名、大小等其他信息)
    • 发送端读取文件内容并发送过去,接受端将缓存里面的内容写入文件

    注:以下发送文件代码参考:http://www.mamicode.com/info-detail-1346172.html

    发送端代码

    #!/usr/bin/env python
    # -*- coding=utf-8 -*-
    
    
    """
    file: send.py
    socket client
    """
    
    import socket
    import os
    import sys
    import struct
    
    
    def socket_client():
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(('127.0.0.1', 6666))
        except socket.error as msg:
            print msg
            sys.exit(1)
    
        print s.recv(1024)
    
        while 1:
            filepath = raw_input('please input file path: ')
            if os.path.isfile(filepath):
                # 定义定义文件信息。128s表示文件名为128bytes长,l表示一个int或log文件类型,在此为文件大小
                fileinfo_size = struct.calcsize('128sl')
                # 定义文件头信息,包含文件名和文件大小
                fhead = struct.pack('128sl', os.path.basename(filepath),
                                    os.stat(filepath).st_size)
                s.send(fhead)
                print 'client filepath: {0}'.format(filepath)
    
                fp = open(filepath, 'rb')
                while 1:
                    data = fp.read(1024)
                    if not data:
                        print '{0} file send over...'.format(filepath)
                        break
                    s.send(data)
            s.close()
            break
    
    
    if __name__ == '__main__':
        socket_client()
    

    接收端代码

    #!/usr/bin/env python
    # -*- coding=utf-8 -*-
    
    
    """
    file: recv.py
    socket service
    """
    
    
    import socket
    import threading
    import time
    import sys
    import os
    import struct
    
    
    def socket_service():
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            s.bind(('127.0.0.1', 6666))
            s.listen(10)
        except socket.error as msg:
            print msg
            sys.exit(1)
        print 'Waiting connection...'
    
        while 1:
            conn, addr = s.accept()
            t = threading.Thread(target=deal_data, args=(conn, addr))
            t.start()
    
    def deal_data(conn, addr):
        print 'Accept new connection from {0}'.format(addr)
        #conn.settimeout(500)
        conn.send('Hi, Welcome to the server!')
    
        while 1:
            fileinfo_size = struct.calcsize('128sl')
            buf = conn.recv(fileinfo_size)
            if buf:
                filename, filesize = struct.unpack('128sl', buf)
                fn = filename.strip('0')
                new_filename = os.path.join('./', 'new_' + fn)
                print 'file new name is {0}, filesize if {1}'.format(new_filename,
                                                                     filesize)
    
                recvd_size = 0  # 定义已接收文件的大小
                fp = open(new_filename, 'wb')
                print 'start receiving...'
    
                while not recvd_size == filesize:
                    if filesize - recvd_size > 1024:
                        data = conn.recv(1024)
                        recvd_size += len(data)
                    else:
                        data = conn.recv(filesize - recvd_size)
                        recvd_size = filesize
                    fp.write(data)
                fp.close()
                print 'end receive...'
            conn.close()
            break
    
    
    if __name__ == '__main__':
        socket_service()

    打开两个终端,分别运行recv.pysend.py脚本,输入待传输文件的全路径和文件名(如:/home/test.txt),你就会在recv.py脚本路径下看到刚输入的传输文件,且文件名为new_****

  • 相关阅读:
    函数
    python操作文件
    POJ-2689-Prime Distance(素数区间筛法)
    POJ-2891-Strange Way to Express Integers(线性同余方程组)
    POJ-2142-The Balance
    POJ-1061-青蛙的约会(扩展欧几里得)
    Educational Codeforces Round 75 (Rated for Div. 2) D. Salary Changing
    Educational Codeforces Round 75 (Rated for Div. 2) C. Minimize The Integer
    Educational Codeforces Round 75 (Rated for Div. 2) B. Binary Palindromes
    Educational Codeforces Round 75 (Rated for Div. 2) A. Broken Keyboard
  • 原文地址:https://www.cnblogs.com/VseYoung/p/socket_1.html
Copyright © 2011-2022 走看看