【python】socket模块

socket

一丶socket最基本的链接

服务端:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  socket#导入socket模块
sk=socket.socket()#实例化socket类
sk.bind(('127.0.0.1',9999,))#绑定ip和端口
sk.listen()#进行监听,sk.listen(num),参数num是表示允许接收多少阻塞在这里的链接

while True:
    conn, address = sk.accept()#接收客户端信息
    print(conn,address)#conn和address分别代表连接和客户端的信息

 

客户端端链接:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  socket
sk=socket.socket()#实例化对象
sk.connect(("127.0.0.1",9999,))#链接ip和端口
sk.close()#关闭链接
#如果在这里连接了,上面的服务端代码就会打印出conn和address

二丶服务端和客户端进行交互

服务端:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  socket#导入socket模块
sk=socket.socket()#实例化socket类
sk.bind(('127.0.0.1',9999,))#绑定ip和端口
sk.listen()#进行监听,sk.listen(num),参数num是表示允许接收多少阻塞在这里的链接
while True:
    conn, address = sk.accept()#接收客户端信息
    conn.sendall(bytes("欢迎致电",encoding='utf-8'))#接收到链接就发送这个字符串给链接的客户端
    while True:
        ret_bytes=conn.recv(1024)#接收客户端发送过来的消息
        acces=str(ret_bytes,encoding='utf-8')#把发送过来的字节码转成utf-8编码
        conn.sendall(bytes(acces+"",encoding='utf-8'))#把字符串转成字节码发给客户端
        #注意:
        #发送的消息一定要是字节码,所以一定要记得要转成字节码(byte),如果是Int类型就先转成str再转成字节码

 

客户端:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  socket
sk=socket.socket()#实例化对象
sk.connect(("127.0.0.1",9999,))#链接ip和端口

while True:
    ret_bytes=sk.recv(1024)#接收服务端发过来的消息
    print(str(ret_bytes,encoding='utf-8'))#把byte字节码转成字符串
    inp=input("请输入内容:")#等待客户输入内容
    sk.sendall(bytes(inp,encoding='utf-8'))#把用户输入的内容发送到服务端
sk.close()#关闭链接

 

三丶上传文件

服务端:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  socket
sk=socket.socket()
sk.bind(("127.0.0.1",9998,))#绑定ip和端口
sk.listen()#进行监听,sk.listen(num),参数num是表示允许接收多少阻塞在这里的链接

while True:
    conn,address=sk.accept()#接收客户端信息
    conn.sendall(bytes("欢迎上传",encoding="utf-8"))#接收到链接就发送这个字符串给链接的客户端
    byes_ret=conn.recv(1024)#接收客户端发过来的文件大小,用于跳出文件写入的循环
    filesize=str(byes_ret,encoding="utf-8")#把字节码转码,转码成字符串
    conn.sendall(bytes("ok",encoding="utf-8"))#收到文件大小号回复给客户端叫它发文件,这一步是为了解决粘包问题
    filehandle = open("new.jpg", "wb")#先创建一个文件
    filepro=0#这个变量是用于储存已经传了多少字节的内容
    while True:
        if filesize==filepro:#如果已传文件长度等于总长度就跳出这个循环
            break
        data=conn.recv(1024)#接收传过来的文件内容
        filehandle.write(data)#将内如写入文件
        filepro=filepro+len(data)#然后更新已经上传的长度
#下面说明一下粘包问题
#拿上面的发送文件说明一下
#在发送文件大小过去服务端的时候就马上执行发送文件内容,此时文件大小还存在内存中,读取文件的内容又加入到内存中
#此时内存的内容全都发送过去服务端,写入文件,此时就会造成文件错误
#所以我们加了接收“conn.sendall(bytes(‘ok’,encoding=‘utf-8’))”这一步,为了是阻断马上执行下面的代码

 

客户端:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import os
sk=socket.socket()
sk.connect(("127.0.0.1",9998,))#连接ip和端口
print(str(sk.recv(1024),encoding="utf-8"))#接收“欢迎上传”这个字符串
fsize=os.stat("ok7lht-ruv.jpg").st_size#获取要上传的文件的大小
sk.sendall(bytes(str(fsize),encoding="utf-8"))#将文件大小发送出去
re=sk.recv(1024)#接收返回“ok”的信息,这一步是为了解决粘包的问题
print(str(re,encoding="utf-8"))#打印出接收ok的信息
with open("ok7lht-ruv.jpg","rb") as f:#打开要读取的文件
    for line in f: #一行一行来读取文件
        sk.sendall(line)#将读取的内容发送给服务端

sk.close()#关闭连接

#下面说明一下粘包问题
#拿上面的发送文件说明一下
#在发送文件大小过去服务端的时候就马上执行发送文件内容,此时文件大小还存在内存中,读取文件的内容又加入到内存中
#此时内存的内容全都发送过去服务端,写入文件,此时就会造成文件错误
#所以我们加了接收“re=sk.recv(1024)#接收返回‘ok’的信息”这一步,为了是阻断马上执行下面的代码

 四丶实现并发操作(主要用到的是select模块)

服务端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import select
import socket

sk1=socket.socket()
sk1.bind(("127.0.0.1",8001,))
sk1.listen()

sk2=socket.socket()
sk2.bind(("127.0.0.1",8002,))
sk2.listen()

sk3=socket.socket()
sk3.bind(("127.0.0.1",8003,))
sk3.listen()

sklist=[sk1,sk2,sk3,]

while True:
    r_list, w_list, e_list = select.select(sklist, [], [], 1)#select模块主要是就监听socket对象哪个发生了变化。发生了变化就会传给r_list
    for i in r_list: #循环发生变化的对象,然后接受变化对象的链接,从而实现并发连接
        conn,address=i.accept()
        index=sklist.index(i)
        conn.send(bytes("hellow word "+str(index),encoding="utf-8"))#发送消息给连接socket对象的客户端

 

posted @ 2017-06-28 15:57  丰study  阅读(121)  评论(0)    收藏  举报