TCP三次握手 TCP_NODELAY python版tcpserver python版tcpclient
- 2015-08-09 19:10:00
- admin
- 原创 1794
一、TCP三次握手
名词术语:
1、SYN,Synchronize Sequence Number,同步序列编号;
三次握手,防止失效的连接请求报文又传送到了服务端,因而产生错误,经过确认才分配资源:
1、客户端发送SYN=j到服务端,进入SYN_SENT状态等待服务端确认;
2、服务端收到SYN必须发送ACK=j+1,同时发送SYN=k,即SYN+ACK,服务端进入SYN_RECV状态;
3、客户端收到SYN+ACK,发送ACK=k+1到服务端,客户端和服务端进入ESTABLISHED状态,三次握手完成;
三次握手产生的两个队列:
1、未完成连接队列,incomplete connection queue,套接字处于SYN_RECV状态。
/proc/sys/net/ipv4/tcp_max_syn_backlog设置队列最大长度,默认1024。
/proc/sys/net/ipv4/tcp_syncookies控制队列是否生效,1启用,0未启用。
2、已完成连接队列,completed connection queue,套接字处于ESTABLISHED状态。
backlog设置队列最大长度,backlog=min(backlog,/proc/sys/net/core/somaxconn),somaxconn默认128。
TCP_NODELAY:
1、TCP默认开启Nagle算法,网络发送和接收使用缓存,以便减少网络包数量,可能造成40毫秒延迟;
2、启动TCP_NODELAY表示禁用Nagle算法,数据直接发送到网络环境,对于延时敏感应用非常有用;
二、python版tcpserver
下载地址:tcpserver.py
def dumpHex(buf):
print 'data length is %d.' % len(buf)
for ch in buf:
print '0x%02x' % ord(ch),
print
def getSocket(ip, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, port))
sock.listen(32)
return sock
def process(connection):
try:
connection.settimeout(5)
while True:
data = connection.recv(1024)
dumpHex(data)
connection.send('server reply!')
time.sleep(5)
except socket.timeout:
print 'time out at %d!' % int(time.time())
except Exception:
print 'connection close!'
def main():
sock = getSocket('localhost', 8080)
while True:
(connection, address) = sock.accept()
process(connection)
connection.close()
三、python版tcpclient
下载地址:tcpclient.py
def dumpHex(buf):
print 'data length is %d.' % len(buf)
for ch in buf:
print '0x%02x' % ord(ch),
print
def getSocket(ip, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = (ip, port)
num = 0
while True:
try:
num += 1
sock.connect(address)
break
except Exception, e:
print 'connecting error, retry %d ...' % num
time.sleep(1)
continue
return sock
def main():
sock = getSocket('127.0.0.1', 8080)
while True:
sock.send('get')
data = sock.recv(1024)
if len(data) > 0: #0-closed from the other end.
dumpHex(data)
continue
else:
break
sock.close()