首页 > 技术文章 > socket

flyhgx 2017-04-10 17:35 原文

socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

socket和file的区别:

  • file模块是针对某个指定文件进行【打开】【读写】【关闭】
  • socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

运用socket()实现文件上传:

服务端在发送数据之前,先把发送数据的长度告诉客户端,要发送多少数据,然后客户端根据这个数据的长度循环接收来解决粘包,传输过程:
服务端:
(1).send #数据长度
(4).recv #收到确认信息,开始下一步发送
send #发送数据

客户端 :
(2).recv #获取数据长度
(3).send #发送确认信息
recv #循环接收
服务端:

#coding:utf-8
import os,sys

import json,socket

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip = ('localhost',10245)
server.bind(ip)
server.listen(5)
conn,addr = server.accept()

recv_size = 0   #用于计算我们已经接收文件大小
recv_file = b'' #用于以二进制的方式存储文件

msg_info = json.loads(conn.recv(1024))
if msg_info.has_key("ack_msg"): #判断我们首次发送过来的的数据头中有没有ack_msg的key
    file_size = msg_info["ack_msg"]["file_size"]
    conn.send("start")
    while recv_size<file_size:
        
        content = conn.recv(1024)
        recv_size += 1024        #每接收一次文件内容,让我们的已接受文件大小+1024
        recv_file += content
    else:
        with open("C:\Users\issuser\Desktop\index2.html","ab+") as f:
            f.write(content)
            print u"传输完成了。。。"



客户端:

#!/user/bin/env python
#coding:utf-8
import socket
import json
import os
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

ip  = ('127.0.0.1',10245)
print type(ip)
client.connect(ip)

file_path = "C:\Users\issuser\Desktop\index.html"
file_name = os.path.basename(file_path)
with open(file_path,"rb") as f:
        content = f.read()
        file_size = len(content)

ack_msg = {"ack_msg":{"file_name":file_name,"file_size":file_size}}
client.send(json.dumps(ack_msg))
ack = client.recv(1024)
if ack == "start":
        client.send (content)

client.close()

运用socket()实现文件分发:

服务端:

#coding:utf-8
import yaml,json,SocketServer

class MyHandler(SocketServer.BaseRequestHandler):
    def setup(self):
        with open('properties') as f:
            cfg = yaml.load(f.read())
            self.cfg = cfg

    def handle(self):
        conn  = self.request  #客户端连接的对象
        print '有客户端连接上了'
        if conn.recv(1024)=='successful':
            with open(self.cfg['filepath']['filepaths']) as f:
                content =f.read()
                print content
                filesize = len(content)
                print filesize
                data = json.dumps({'filesize':filesize})
                conn.send(data)
        if conn.recv(1024)=='start':
            conn.send(content)
        finish_msg = conn.recv(1024)
        print finish_msg
    def finish(self):
        print "finish"
if __name__ == "__main__":
    ip = ('localhost',9999)
    server = SocketServer.ThreadingTCPServer(ip,MyHandler)
    server.serve_forever()

客户端:

#coding:utf-8
import  json,socket
import sys,time

client = socket.socket()
ip = ('localhost',9999)
for i  in range(3):
    try:
        client.connect(ip)
        break
    except Exception  as e:
       print "连接失败了"
       time.sleep(3)
else:
    sys.exit('重连3次失败,系统退出')


client.send("successful")

data = client.recv(1024)
if data in 'filesize':
    filesize = data.get('filesize')

    client.send('start')
recv_size = 0
recv_file = b''

while recv_size <recv_size:
    content = client.recv(1024)
    recv_size+=1024
    recv_file+=content
else:
    with open('C:\Users\Administrator\Desktop\config.py','wb+')as f:
        f.write(recv_file)
client.send("传送完成")

推荐阅读