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

socket不关心用什么协议,统一提供方法函数
2020/01/14 01-UDP编程和群聊UDPServer
这是TCP的
server端要socket,要绑定bind,listen,accept,接入连接后,要返回新的 socket和客户端socket进行连接,最后用完关闭,socket占用资源
客户端就是,socket,连接connect,收发数据,用完close

UDP和TCP的差异,UDP是无连接协议,TCP需要三次握手,4次断开,UDP不握手,也就没有断开的说法了,2020/01/14 01-UDP编程和群聊UDPServer2020/01/14 01-UDP编程和群聊UDPServer
UDP起socket,绑定bind,就可以进行收和发了,可以用recv ,send 也可以用recvfrom,sendto
客户端可以连接也可以不用连接,服务端发送数据,不关心client是否接收到
2020/01/14 01-UDP编程和群聊UDPServer2020/01/14 01-UDP编程和群聊UDPServer

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

2020/01/14 01-UDP编程和群聊UDPServer
这样就把消息发回来了,端对端要发送数据的时候,会临时绑定socket端口,一般1024以上,最大65535

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

2020/01/14 01-UDP编程和群聊UDPServer
recv阻塞等数据
2020/01/14 01-UDP编程和群聊UDPServer
发送一个数据
2020/01/14 01-UDP编程和群聊UDPServer
这样就收到了,有数据到了缓冲区就读出来,不关心数据到没到
2020/01/14 01-UDP编程和群聊UDPServer2020/01/14 01-UDP编程和群聊UDPServer
一般缓冲区大小都是1024
2020/01/14 01-UDP编程和群聊UDPServer
目前为止,sendto,recvfrom,recv都使用了,还剩send没有使用

send没有发送成功,是因为不知道对端地址2020/01/14 01-UDP编程和群聊UDPServer
使用connect,无连接协议使用connect2020/01/14 01-UDP编程和群聊UDPServer
成功,正常退出是02020/01/14 01-UDP编程和群聊UDPServer
现在connect一下,远端地址就OK了,相当于告诉了远端地址
2020/01/14 01-UDP编程和群聊UDPServer
UDP客户端创建socket就可以recv和send了,recv,别人要发给你,就需要知道你的地址,client没有绑定,别人给你发数据,是无法接收数据的2020/01/14 01-UDP编程和群聊UDPServer
client没有绑定,别人给你发数据,是无法接收数据的,
现在一启动就recv,client没有占用任何socket端口,别人无法发送数据

2020/01/14 01-UDP编程和群聊UDPServer
也就是自己是A端,发送任何数据,不管对方存在与否,或者收到与否2020/01/14 01-UDP编程和群聊UDPServer
UDP的socket对象创建后,是没有占用本地地址和端口的
UDP编程中bind、connect、 send、 sendto、 recv、 recvfrom方法使用

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

作为UDP服务,其实跟TCP一样,对服务端来讲必须绑定一个固定的端口,让别人来访问,TCP要监听,UDP绑定即可
laddr和raddr搞定,下面的方法想用什么都可以
2020/01/14 01-UDP编程和群聊UDPServer
send看到raddr就可以使用,
有了laddr 才可以使用recv,recvfrom

所以laddr和raddr决定你用什么方法2020/01/14 01-UDP编程和群聊UDPServer2020/01/14 01-UDP编程和群聊UDPServer
是否可以构建UDP版的群聊软件

构建UDP群聊软件

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

2020/01/14 01-UDP编程和群聊UDPServer
给线程起个名字
2020/01/14 01-UDP编程和群聊UDPServer

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

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

现在发送一个hello
2020/01/14 01-UDP编程和群聊UDPServer
这里也收到了
2020/01/14 01-UDP编程和群聊UDPServer
现在群发没问题,有人走了,怎么直到对方走了的问题还没解决
2020/01/14 01-UDP编程和群聊UDPServer