【python基础】socket网络编程总结

网络编程

1、TCP三次握手&四次挥手

流程如下:

tcp三次握手
client                  			server
SYN=1,ACK=0,seq=x			->
							<-      SYN=1,ACK=1,seq=y,ack=x+1
ACK=1,seq=x+1,ack=y+1		->

tcp四次挥手
client                  			server
FIN=1,seq=u					->
							<-		ACK=1,seq=v,ack=u+1
							<-		FIN=1,ACK=1,seq=w,ack=u+1
ACK=1,seq=u+1,ack=w+1		->							

2、套接字

套接字:实现网络编程进行数据传输的一种技术手段
在python中使用:import socket
流式套接字(SOCK_STREAM):以字节流方式传输数据,实现tcp网络传输
数据报套接字(SOCK_DGRAM):以数据报形式传输数据,实现udp网络传输

3、TCP套接字编程

3.1、服务端流程

1、创建socket套接字
2、绑定地址bind
3、监听listen
4、阻塞等待连接accept
5、数据收发send/recv
6、关闭连接close

1、创建套接字
sk = socket.socket(socket_family=AF_INET, socket_type=SOCK_STREAM, proto=0)
socket_family:
	网络地址类型,AF_INET表示IPV4;
	socket_type套接字类型(SOCK_STREAM,SOCK_DGRAM)
	proto通常为0,选择子协议

2、绑定地址
sk.bind(addr)
绑定本机网络地址
参数:二元元祖:(ip, port),如:('0.0.0.0', 8888)

注意:绑定本地主机地址有4种方式:127.0.0.1、'localhost'、'0.0.0.0'、实际IP(如:123.56.67.111)
方式1(127.0.0.1/localhost):以该方式绑定,本地主机客服端可通过127.0.0.1访问,但其他主机不能访问;
方式2(0.0.0.0):本地主机可以通过127.0.0.1访问,其他主机可通过123.56.67.111访问;
方式3(123.56.67.111):本地和其他主机可通过123.56.67.111访问

3、设置监听
sk.bind(n)
将套接字设置为监听套接字,确定监听队列大小,n在linux下设置后不生效
监听了之后客户端就可以连接了

4、等待处理客户端连接请求
client, addr = sk.accept()
阻塞等待处理客户端请求,accept()为阻塞函数,程序执行到这儿暂停
返回值:client客户端连接套接字;addr连接的客户端地址

5、消息收发
data = client.recv(buffersize)
接收客户端消息,阻塞函数
参数:每次最多接收消息大小
返回值:接收到的内容

n = client.send(data)
功能:发送消息
参数:要发送的内容 bytes形式
返回值:发送的字节数

6、关闭套接字
sk.close()

3.2、客户端流程

1、创建socket
2、连接connect
3、收发消息send/recv
4、断开连接close

3.3、TCP粘包

原因:TCP以字节流传输,没有消息边界,多次发送的消息被一次接收,就会形成粘包。
影响:如果每次发送内容是一个独立的含义,需要接收端独立解析此时粘包会有影响。
处理方法:
1、人为添加消息边界
2、控制发送速度

4、UDP套接字编程

4.1、服务端流程

1、创建socket
2、绑定bind
3、消息收发recvfrom/sendto
4、断开连接close

4.2、客户端流程

1、创建socket
2、收发信息sendto/recvfrom
3、断开连接close

5、代码实例

5.1、TCP SERVER

import socket

#创建tcp套接字
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

#绑定地址
sk.bind(('127.0.0.1', 8888))

#设置监听
sk.listen(5)

#阻塞等待处理连接
while True:
    print("Waiting for connect...")
    try:
        client, addr = sk.accept()
        print("Connect from %s" % str(addr))  #打印连接的客户端地址
    except Exception as e:
        print(e)
        continue

    #收发消息
    while True:
        data = client.recv(1024)
        if not data:		#客户端断开连接会立即返回一个空
            print("Data trans end.")
            break
        print("received:%s" % data.decode())
        n = client.send(b"Data received!")
        print("send %d bytes" % n)
    client.close()

#关闭套接字
sk.close()

5.2、TCP CLIENT

import socket

#创建tcp套接字
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

#连接服务器
service_addr = ("127.0.0.1", 8888)
sk.connect(service_addr)

#收发消息
while True:
    data = input("Please input msg>>")
    if not data:
        break
    sk.send(data.encode())
    data = sk.recv(1024)
    print("Server:%s" % data.decode())

#关闭
sk.close()

运行结果:

客户端:
Please input msg:>>abc
Server response:Data received!
Please input msg:>>

服务端:
Waiting for connect...
Connect from ('127.0.0.1', 13535)
received:abc
send 14 bytes
Data trans end.
Waiting for connect...

5.3、UDP SERVER

import socket

#创建udp套接字
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)

#绑定地址
sk.bind(('127.0.0.1', 8888))

#收发消息
while True:
    try:
        data, addr = sk.recvfrom(1024)
        print("Received msg:" + data.decode() + " from " +str(addr))
        sk.sendto(b'UDP Data received!', addr)
    except Exception as e:
        print(e)
        continue

#关闭
sk.close()

5.3、UDP CLIENT

from socket import *

# 服务器地址
ADDR = ('127.0.0.1',8888)

# 创建套接字
sockfd = socket(AF_INET,SOCK_DGRAM)

# 收发消息
while True:
    data = input("Please input msg>>")
    if not data:
        break
    sockfd.sendto(data.encode(),ADDR)
    msg,addr = sockfd.recvfrom(1024)
    print("From server:",msg.decode())

sockfd.close()

运行结果:

客户端:
Please input msg>>abc
From server: UDP Data received!
Please input msg>>def
From server: UDP Data received!
Please input msg>>

服务端:
Received msg:abc from ('127.0.0.1', 56066)
Received msg:def from ('127.0.0.1', 56066)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值