socket网络编程及可靠性实现

前一段时间做时延测试,今天抽空总结下除了HAProxy配置之外的收获。

时延测试主要是利用TCP包的请求与响应来实现,形同于ping包,那为什么不使用ping包直接来测试呢?因为合作机房与自研机房是没办法直接通信的,这之间需要建立专用链路,而ping包是通不过去的,因此就需要使用socket去模拟ping包。

其中socket传输上会出现以下几种情况:

一、如果socket包在传输过程中丢失或者乱序怎么办?

解决方法:传seq序号来标识每个包。

二、在server端如果一次read出了好几个包,那么我们怎么把第一个包分离出来呢?

解决方法:需要传的信息包括length(包的长度)、timestamp(时间戳)、seq(序号),首先我们length的长度固定为int型四字节,timestamp为float类型四字节,seq为int类型四字节,这样双方先约定好信息包及各个信息的长度,然后将length用struct模块的pack()函数组进包里,同时二进制占位是不变的,然后再将组好的length、timestamp、seq一起再用struct.pack()组成大包,这样客户端接收到一个信息就先把这个信息unpack(),然后取出前四个字节unpack()这样信息的长度length就知道了,然后我们从length开始向后面取出length长度的数据即是我们需要的timestamp和seq了,至此我们就把第一个包分离出来了。


测速的源代码贴上:

Server端代码

import socket
import datetime
import struct
import json
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind(('xxxx',3366))

s.listen(10)
while True:
	conn, addr = s.accept()
	print "Connect with ", addr
  	while True:
  		f = file('testSpeedserver.txt', 'a+')
		d = conn.recv(1024)
		dataLen = len(d)
		if dataLen>=4:
			length = struct.unpack("!I", d[0:4])
			if dataLen>=length[0]:
				strBody = d[4:length[0]]
				body = json.loads(strBody)
				#print "%d bytes from xxxx: seq=%d timestamp=%.3f ms" %(dataLen, body['seq'], body['timestamp'])
				tm = "%.3f" %(body['timestamp'])
				f.write(str(dataLen)+" bytes from xxxx: seq="+str(body['seq'])+" timestamp="+str(tm)+" ms\n")
				conn.send(d)
f.close()
s.close()

Client端的代码

import socket
import datetime
import time
import struct
import json

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect(('xxxx', 3366))


seq = 1;

while seq:
	f = file('testSpeedclient.txt', 'a+')
	now = datetime.datetime.now()
	nowtime = now.time()
	tv_send = nowtime.hour*3600000 + nowtime.minute*60000 + nowtime.second*1000 + nowtime.microsecond*1.0/1000
	#send_msg = str(seq)+"/"+str(tv_send)
	body = {
		"seq":seq,
		"timestamp":tv_send
	}
	strBody = json.dumps(body)
	length =  len(strBody)+4
	strLen = struct.pack("!I", length)
	send_msg = strLen+strBody
	s.send(send_msg)
	d = s.recv(1024)
	now = datetime.datetime.now()
	nowtime = now.time()
	tv_recv = nowtime.hour*3600000 + nowtime.minute*60000 + nowtime.second*1000 + nowtime.microsecond*1.0/1000
	dataLen = len(d)
	if dataLen>=4:
		length = struct.unpack("!I", d[0:4])
		if dataLen>=length[0]:
			strBody = d[4:length[0]]
			body = json.loads(strBody)
	#print "%d bytes from xxxx: seq=%d timestamp=%.3f ms time=%f ms" %(dataLen, body['seq'], tv_send, (tv_recv-body['timestamp']))
	tm = "%.3f" %(tv_recv-body['timestamp'])
	sendtm = "%.3f" %(tv_send)
	f.write(str(dataLen)+" bytes from xxxx: seq="+str(body['seq'])+" timestamp="+str(sendtm)+" ms time="+str(tm)+" ms\n")
	seq = seq + 1
	time.sleep(1)
f.close()
s.close()


猜你喜欢

转载自blog.csdn.net/allesa/article/details/52312220