socket

服务器端
import
socket
#创建socket对象 sk
= socket.socket()

#绑定IP、端口 sk.bind((
"192.168.0.102",8888,))
#只接受5个等待连接 sk.listen(5)
#等待客户端的连接,接收到连接之前阻塞其下的代码执行,con是服务器与接收到的客户端之间的连接,两端基于con传递消息 #address是客户端的信息(IP,端口) #因为accept接受客户端连接一次之后就会断开,所以加一个while循环,不停的接受新连接 while True: con,address = sk.accept() print(address,con)
客户端:

import socket

obj = socket.socket()

#连接 obj.connetc((
"192.168.0.102", 8888,)) #断开连接 obj.close()
服务器向客户端发送内容:
##通过sendall()可以发消息,通过recv()可以接收消息
import socket 
sk
= socket.socket()
sk.bind((
"192.168.0.102",8888,))
sk.listen(
5)
while True:
  con,address
= sk.accept()
  con.sendall(bytes(
"hello world",encoding = "utf-8"))#python2.7可以直接传字符串,3.0之后需要转换成字节
  print(address,con)

客户端接收:

import socket

obj = socket.socket()
obj.connetc(("192.168.0.102",8888,))
#1024是设置的最大接受字节数,一次接收不完,下次接收
#在客户端,recv同样跟服务器端的accept一样有阻塞效果,如果服务器没有返回,客户端会一直等待。这个阻塞是等待服务器发数据,accept的阻塞是等待用户来连接
ret_bytes = obj.recv(1024)
ret_str = str(ret_bytes,encoding = "utf-8")
print(ret_str)
obj.close()

 

下面实现这样一个效果:客户端连上服务器后,用一个input循环输入消息,服务器收到后加一个“wonderful”再返回:

服务器:
import
socket sk = socket.socket() sk.bind(("192.168.0.102",8999,)) #只接受5个等待连接 sk.listen(5) #等待客户端的连接,阻塞其下的代码执行,con是服务器与接收到的客户端之间的连接 #address是客户端的信息(IP,端口) #因为accept接受客户端连接一次之后就会断开,所以加一个while循环,以便可以不停的接受新连接 while True: con,address = sk.accept() con.sendall(bytes("hello world",encoding = "utf-8"))#python2.7可以直接传字符串,3.0之后需要转换成字节 print(address,con) #使用循环不停接收客户端消息,无论接收到什么,都在后面加一个“wonderful”再发送回去 while True: ret_bytes = con.recv(1024) ret_str = str(ret_bytes,encoding = "utf-8")
     if ret_str == "q":
       break con.sendall(bytes(ret_str
+"wonderful",encoding = "utf-8"))

客户端:
import socket

obj = socket.socket()
obj.connect(("192.168.0.102",8999,))

ret_bytes = obj.recv(1024)
ret_str = str(ret_bytes,encoding = "utf-8")
print(ret_str)

while True:
    inp = input("input:")
   if inp == "q"   obj.sendall(bytes(inp,encoding
= "utf-8"))
     break
   else:
     obj.sendall(bytes(inp,encoding = "utf-8"))   rec_bytes
= obj.recv(1024)   rec_str = str(rec_bytes,encoding = "utf-8")   print(rec_str) obj.close()

 

使用socket 从客户端发送文件到服务器端:

服务器端:
import socket sk
= socket.socket() sk.bind(("127.0.0.1",8888)) sk.listen(5) while True: con,address = sk.accept() size = con.recv(1024)#这里会接收到客户端发来的文件大小字节数 str_size = str(size) #将字节转换成字符串 total = str_size has_recv = 0 f = open("hahahahahha.jpg","wb") #先创建一个文件,等待写入 while True: if has_recv == total: #文件接收完毕,has_recv应该正好等于total的大小 break data = con.recv(1024) f.write(data) has_recv += len(data) #每循环一次,has_recv的值加上data的文件大小(长度) f.close()

客户端:
import socket
import os

obj = socket.socket()
obj.connect(("127.0.0.1",8888,))

size = os.stat("123.jpg").st_size #os.stat("filename").st_size 获取filename的文件大小字节数
obj.sendall(bytes(str(size),encoding="utf-8")) #将这个文件大小转换成bytes发送给服务器

with open('123.jpg','rb') as f:
for line in f:
obj. sendall(line)

obj.close()

粘包:当客户端第一次发送文件大小的数据包时,数据包先进入缓冲区。如果还没有从缓冲区发送之前,下面的文件已经读取了几行数据,而且也马上进入了缓冲区的话,又一起发送给服务器,就可能在服务器端接收的文件大小就不是正确的数据。(可能是本来的文件大小加上了同时在缓冲区一起发送的的那几行数据),这种情况叫粘包。

解决方法:

1、比较low的方法,可以在客户端发送文件大小后,放一个sleep,等待1秒确保缓冲区内容发送之后再执行下面的代码

2、在客户端发送大小之后,放一个obj.recv(1024),这样recv就会阻塞下面的代码,直到它接收到服务器端返回的数据,同时服务器端接收到文件大小后sendall()一个数据,客户端接收到之后,执行下面的发送文件代码。

服务器端:
import socket

sk = socket.socket()
sk.bind(("127.0.0.1",8888))
sk.listen(5)

while True:
    con,address = sk.accept()
    size = con.recv(1024)#这里会接收到客户端发来的文件大小字节数

con.sendall(bytes("ok",encoding = "utf-8")) #服务器收到大小之后来一个sendall()
str_size = str(size) #将字节转换成字符串 total = str_size has_recv = 0 f = open("hahahahahha.jpg","wb") #先创建一个文件,等待写入 while True: if has_recv == total: #文件接收完毕,has_recv应该正好等于total的大小 break data = con.recv(1024) f.write(data) has_recv += len(data) #每循环一次,has_recv的值加上data的文件大小(长度) f.close() 客户端: import socket import os obj = socket.socket() obj.connect(("127.0.0.1",8888,)) size = os.stat("123.jpg").st_size #os.stat("filename").st_size 获取filename的文件大小字节数 obj.sendall(bytes(str(size),encoding="utf-8")) #将这个文件大小转换成bytes发送给服务器
obj.recv(1024) #客户端发送文件大小后,来个recv(),先阻塞下面代码,等服务器的sendall(),已经在缓冲区的文件大小就会及时发送出去,不会跟下面的文件一起进入缓冲区
with open(
'123.jpg','rb') as f: for line in f: obj. sendall(line) obj.close()

 

posted @ 2018-10-11 11:43  greenfan  阅读(117)  评论(0)    收藏  举报