socket(套接字)初使用

时间:2023-02-08 18:35:58

socket层

socket(套接字)初使用

socket:是应用层与TCP/IP协议通信的中间软件抽象层,是一组接口,在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/IP协议隐藏在socket接口后面。

 

socket(套接字)初使用

 

基于TCP协议的socket

tcp是基于链接,必须先启动服务端,然后在启动客户端去链接服务端

server端

socket(套接字)初使用socket(套接字)初使用
 1 import socket
 2 sk=socket.socket()
 3 sk.bind(('127.0.0.1',9000)) #把地址绑定到套接字
 4 sk.listen()                           #监听链接
 5 conn,addr = sk.accept()#接受客户端链接
 6 ret=conn.recv(1024)     #接受客户端信息
 7 print(ret)                              #打印客户端信息
 8 conn.send(b'hi')               #向客户端发送信息
 9 conn.close()               #关闭客户端套接字
10 sk.close()                    #关闭服务器套接字
server端

 

client

socket(套接字)初使用socket(套接字)初使用
1 import socket
2 sk=socket.socket()           #创建客户套接字
3 sk.connect(('127.0.0.1',9000))       尝试链接服务器
4 sk.send(b'hello')
5 ret=sk.recv(1024)                  #对话
6 print(ret)
7 sk.close()                    #关闭客户套接字
client

 

问题:有的同学在重启服务端时可能遇到

 

socket(套接字)初使用

解决办法:

socket(套接字)初使用socket(套接字)初使用
 1 #加入一条socket配置,重用ip和端口
 2 import socket
 3 from socket import SOL_SOCKET,SO_REUSEADDR
 4 sk = socket.socket()
 5 sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
 6 sk.bind(('127.0.0.1',8898))  #把地址绑定到套接字
 7 sk.listen()          #监听链接
 8 conn,addr = sk.accept() #接受客户端链接
 9 ret = conn.recv(1024)   #接收客户端信息
10 print(ret)              #打印客户端信息
11 conn.send(b'hi')        #向客户端发送信息
12 conn.close()       #关闭客户端套接字
13 sk.close()        #关闭服务器套接字(可选)
View Code

 

 

          关于UDP协议的socket

udp是无链接的,启动服务之后可以直接接受消息,不需要提前建立链接。

server端

socket(套接字)初使用socket(套接字)初使用
1 import socket
2 udp_sk=socket.socket(type=socket.SOCK_DGRAM)
3 udp_sk.bind(('127.0.0.1',9000))
4 msg,addr=udp_sk.recvfrom(1024)
5 print(msg)
6 udp_sk.sendto(b'hi',addr)
7 udp_sk.close()
import

client端

socket(套接字)初使用socket(套接字)初使用
1 import socket
2 ip_port=('127.0.0.1',9000)
3 udp_sk=socket.socket(type=socket.SOCK_DGRAM)
4 udp_sk.sendto(b'hello',ip_port)
5 back_msg,addr=udp_sk.recvfrom(1024)
6 print(back_msg.decode('utf-8'),addr)
client

socket参数的详解

socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)

创建socket对象的参数说明:

family 地址系列应为AF_INET(默认值),AF_INET6,AF_UNIX,AF_CAN或AF_RDS。
(AF_UNIX 域实际上是使用本地 socket 文件来通信)
type 套接字类型应为SOCK_STREAM(默认值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。
SOCK_STREAM 是基于TCP的,有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料传送。 
SOCK_DGRAM 是基于UDP的,无保障的面向消息的socket,多用于在网络上发广播信息。
proto 协议号通常为零,可以省略,或者在地址族为AF_CAN的情况下,协议应为CAN_RAW或CAN_BCM之一。
fileno 如果指定了fileno,则其他参数将被忽略,导致带有指定文件描述符的套接字返回。
与socket.fromfd()不同,fileno将返回相同的套接字,而不是重复的。
这可能有助于使用socket.close()关闭一个独立的插座。