UDP:相当于写信,需要IP,端口,内容 然后一起发出。不安全,甚至可能丢或者被别人收走
TPC:相当于打电话,连接时需要应答,超时后会验证,比较麻烦但是比较安全。虽然内容可能丢失,
套接字是全双工的
UDP:
流程:
1.创建套接字
2.接受/发送数据
3.关闭套接字
发送数据
创建套接字:
概念:s = socket.socket(AddressFamily(协议IPV4,IPV6),Type(类型TCP,UDP)) 创建的是对象
例子:s = socket.socket(socket.AF_INET,socket.SOCK_STREAM/socket.SOCK_DGRAM)
发送数据:
s.sendto(b'hello',('127.0.0.1',8080))
关闭套接字:
s.close()
接收数据
创建套接字:
s = socket.socket(AF_INET,SOCK_DGARM)
绑定信息:
addr=('',7788) 前面代表IP,后面代表端口,如果不写就默认为本机IP
s.bind(addr)
接受数据
1.recv_date = s.recvfrom(1024) # 数字表示本次接收的最大字节数
recv_date 的内容是以元组表示(内容,(发送方的IP,发送方的端口))
所以想要得到内容是就是 recv_date[0] 需要解码( 应该根据电脑判断)才能正确显示(如果是Windos发送的要用gbk解码)
想得到数据发送人的信息就是recv_date[1]
关闭套接字:
s.close()
温馨提示:recvrecv_date = s.recvfrom(1024) 接收时 如果没有数据就会堵塞
TCP:
明确区分服务端和客户端,发送时,好像都不需要自己绑定IP和端口
1.客户端和UDP使用类似:
1.创建套接字
tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
2.连接服务器的IP和端口
tcp_client.connect((IP,PORT)) 元组
3.发送数据:
send_data = input('请输入发送内容:')
tcp_client.send(send_data.encode('utf-8'))
4.关闭套接字:
tcp_client.close()
2.服务端
1.创建套接字:
tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
2.绑定属于自己的IP和端口: (bind)
tcp_server.bind(('',7788)) # 一定要绑定IP和端口,就跟110一样,是固定的,能让人随时知道
3.使套接字变成可以被动链接:(listen)
tcp_server.listen(128) # 后面的数字一般为128,虽然不同的数字可能会稍微影响同一时刻的客户端的接入数量,但最终接入数量还是由操作系统自己决定)
4.可以通过设置xx.setblocking(false) ,让套接字变为非堵塞的,即如果accept 没有用户到来也不会堵塞,但是会产生异常,所以就可以用try来解决
5.等待用户连接:(accept)
client_socket,client_add = tcp_server.accept() # 这兄弟会返回一个元组(一个新的套接字,地址),而且堵塞,直到有人链接进来
6.接受/发送数据:(recv/send)
接受:recv_data = client_socket.recv(1024)
发送:client_socket.send('OK接收到了 '.encode('gbk'))
温馨提示:
1.在 accept 前加循环 为循环为多个客户端服务
2.在 recv 前加循环,在为多个客户服务时,循环为一个客户服务
3.如果客户端解堵塞有两种原因:
1.对方发送数据 ,所以 recv 便解堵塞
2.对方调用了 close() 也会
4.服务端在接收到文件名时应该用try来打开文件,不应该用with open来打开否则,如果文件名不存在,用with open 会出错误
5.客户端要判断服务端发送的数据是否为空,不然会创建空文本
总的注意事项:
1. tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器,更无法链接到服务器
2. tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip、port等信息就好,本地客户端可以随机。而且可以避免打开服务器时发生端口问题
3. tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
4.当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信
5.当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
6. listen后的套 接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
7.关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
8.关闭accept返回的套接字意味着这个客户端已经服务完毕
9.当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线