2020/01/14 01-UDP编程和群聊UDPServer

socket不关心用什么协议,统一提供方法函数
在这里插入图片描述
这是TCP的
server端要socket,要绑定bind,listen,accept,接入连接后,要返回新的 socket和客户端socket进行连接,最后用完关闭,socket占用资源
客户端就是,socket,连接connect,收发数据,用完close

UDP和TCP的差异,UDP是无连接协议,TCP需要三次握手,4次断开,UDP不握手,也就没有断开的说法了,在这里插入图片描述在这里插入图片描述
UDP起socket,绑定bind,就可以进行收和发了,可以用recv ,send 也可以用recvfrom,sendto
客户端可以连接也可以不用连接,服务端发送数据,不关心client是否接收到
在这里插入图片描述在这里插入图片描述

创建UDPsocket对象,有了对象,就可以bind(元组)
recv收到多大数据
在这里插入图片描述在这里插入图片描述
调试一下
在这里插入图片描述
现在没有端口
在这里插入图片描述
F8继续向下运行,绑定
在这里插入图片描述在这里插入图片描述
UDP不需要listen就可以了,F9跑起来
在这里插入图片描述
再次发送数据在这里插入图片描述
这样就收到了,但是看不到谁传的数据
在这里插入图片描述
这时候recvfrom就起作用了
在这里插入图片描述
这样可以知道对端是谁
在这里插入图片描述
现在可以服务器给对端回消息, 参数解构和encode转bytes
在这里插入图片描述(send和send都需要bytes),sendto 给谁很重要,地址很重要在这里插入图片描述

在这里插入图片描述
这样就把消息发回来了,端对端要发送数据的时候,会临时绑定socket端口,一般1024以上,最大65535

在这里插入图片描述
现在10000没人使用
在这里插入图片描述
但是依然可以发出去,UDP不关心收没收到,是无连接的协议
在这里插入图片描述
服务器端编程:
1.socket
2.bind绑定
3.收发数据
4.关闭,释放资源
在这里插入图片描述
recv是从缓冲区获取数据,不关心从哪里来,recvfrom是拿到数据,这个数据包包含从哪来的信息,recvfrom可以把来的信息解开,通过返回元组告诉你在这里插入图片描述
UDP客户端创建socket后就可以直接收发了在这里插入图片描述
创建UDPserver在这里插入图片描述
各是各的协议,是不同端口,TCP,UDP在这里插入图片描述
写客户端
sendto要把消息发给哪里,但是send其实也是可以用

在这里插入图片描述
recv阻塞等数据
在这里插入图片描述
发送一个数据
在这里插入图片描述
这样就收到了,有数据到了缓冲区就读出来,不关心数据到没到
在这里插入图片描述在这里插入图片描述
一般缓冲区大小都是1024
在这里插入图片描述
目前为止,sendto,recvfrom,recv都使用了,还剩send没有使用

send没有发送成功,是因为不知道对端地址在这里插入图片描述
使用connect,无连接协议使用connect在这里插入图片描述
成功,正常退出是0在这里插入图片描述
现在connect一下,远端地址就OK了,相当于告诉了远端地址
在这里插入图片描述
UDP客户端创建socket就可以recv和send了,recv,别人要发给你,就需要知道你的地址,client没有绑定,别人给你发数据,是无法接收数据的在这里插入图片描述
client没有绑定,别人给你发数据,是无法接收数据的,
现在一启动就recv,client没有占用任何socket端口,别人无法发送数据

在这里插入图片描述
也就是自己是A端,发送任何数据,不管对方存在与否,或者收到与否在这里插入图片描述
UDP的socket对象创建后,是没有占用本地地址和端口的
UDP编程中bind、connect、 send、 sendto、 recv、 recvfrom方法使用

在这里插入图片描述在这里插入图片描述
bind方法,占用本地地址和端口,laddr= local addr,立即占用,不需要listen
在这里插入图片描述
会随机立即占用本地地址和端口(会用同网段来连接),连接对方就需要自己也有端口,然后连接远端的地址和端口,将你的当前socket的远端地址填充上,所以connect之后直接send是没有问题的
在这里插入图片描述
不connect,直接用sendto,会立即给自己绑定地址和端口(这样才能发送数据),sendto之后,就知道对端的地址,然后再send就没什么问题
在这里插入图片描述
sendto到达了,send没到达。sendto是立即绑定本地地址在这里插入图片描述
sendto是立即绑定本地地址在这里插入图片描述
sendto没有说绑定对端地址
在这里插入图片描述
connect就有raddr,远端的地址和端口在这里插入图片描述
connect方法解决laddr和raddr,sendto解决laddr,connect需要和connect配合,才能给raddr发送数据在这里插入图片描述
laddr本地端口地址,raddr远端地址和断开
如够要recv,laddr本地端口地址,sendto会马上申请一个laddr给你使用,但是raddr没有,所以下面用send肯定不行

作为UDP服务,其实跟TCP一样,对服务端来讲必须绑定一个固定的端口,让别人来访问,TCP要监听,UDP绑定即可
laddr和raddr搞定,下面的方法想用什么都可以
在这里插入图片描述
send看到raddr就可以使用,
有了laddr 才可以使用recv,recvfrom

所以laddr和raddr决定你用什么方法在这里插入图片描述在这里插入图片描述
是否可以构建UDP版的群聊软件

构建UDP群聊软件

服务肯定要start,stop,中间有收发,recv要阻塞,可能需要用到多线程在这里插入图片描述
初始化的时候,应该从配置文件中读取,json库可以直接从object库读取,bind了就可以直接对外提供 服务了在这里插入图片描述在这里插入图片描述
stop就直接close
在这里插入图片描述
main方法还是交互式的,while true 死循环在这里插入图片描述
这样可以来回进行处理在这里插入图片描述
但是现在上面的阻塞,下面的主线程也阻塞,主线程阻塞不合适,就需要来回处理的提取出来在这里插入图片描述
recv就需要开启多线程,现在就死循环接收数据
在这里插入图片描述
可以加入打印信息,消息来自哪里,然后给谁回消息
在这里插入图片描述
运行试试
在这里插入图片描述
端口起来了
在这里插入图片描述
创建UDPclient在这里插入图片描述在这里插入图片描述
起了线程

在这里插入图片描述
给线程起个名字
在这里插入图片描述

我们现在就起了一个线程
在这里插入图片描述两个UDPclient链接试试在这里插入图片描述
一个recv线程和一个主线程就够了
在这里插入图片描述
这个只是简单的业务雏形在这里插入图片描述
TCP绑定的时候用了socket,然后连接过来都要创建新的socket进行通讯
到目前为止,UDP的socket就一个
只有一个socket就需要注意释放资源的时候释放谁

在这里插入图片描述
写群聊的时候,多线程用到字典,有人写入,有删除,关键是遍历的时间可能比较长,有可能被打断,读写的时候,size发生变化会抛出异常,
如果所有的语句是读写,那没关系,因为是原子操作,但是涉及到遍历就出问题了,没遍历完,别人要修改字典,就需要用到锁
在这里插入图片描述
TCP的时候,每建立一个链接就知道对端是谁,而UDP是不知道的,没有三次握手,不知道对端是谁
现在是单聊,要改成群聊,先写一个不用字典的,(元组,列表,set),先试试set在这里插入图片描述
set先试试在27行里存对端的地址,不去重,如果一个客户端连接你一百次,在列表重复了100次,raddr本来是个元组。可hash是可以去重的,现在但凡连过都记录下来在这里插入图片描述
消息准备好了,对端地址拿到了,就需要遍历发送消息,(但是如果人走了,就需要删除一个地址,但是不知道谁离开了)
在这里插入图片描述
如何判断人走了,首先客户端友好离开,就可以主动删除,如果不友好,没打招呼就走了,(该如何解决)

现在发送一个hello
在这里插入图片描述
这里也收到了
在这里插入图片描述
现在群发没问题,有人走了,怎么直到对方走了的问题还没解决
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值