首页 > 编程语言 >使用select实现一个基于UDP的一对一即时聊天程序。

使用select实现一个基于UDP的一对一即时聊天程序。

时间:2024-06-01 17:35:22浏览次数:12  
标签:UDP 一对一 ret rdset buffer int serverAddr sizeof select

注意事项

  • UDP通信时,client要先给server发送消息,这样server才能知道client的信息

代码

//server
#include <func.h>

#define BUFFSIZE 1024

int main()
{
    int sfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sfd == -1){
        perror("socket");
    }

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8080);
    serverAddr.sin_addr.s_addr = inet_addr("192.168.44.128");

    int ret = bind(sfd,(const struct sockaddr*)&serverAddr,sizeof(serverAddr));
    if(ret == -1){
        perror("bind");
    }

    char buffer[BUFFSIZE];

    struct sockaddr_in clientAddr;
    fd_set rdset;
    int maxfd = STDIN_FILENO;
    while(1){
        FD_ZERO(&rdset);
        FD_SET(sfd,&rdset);
        FD_SET(STDIN_FILENO,&rdset);
        if(sfd > maxfd) maxfd = sfd;

        select(maxfd + 1,&rdset,NULL,NULL,NULL);
        
        if(FD_ISSET(sfd,&rdset)){
             memset(&clientAddr,0,sizeof(clientAddr));
             memset(&buffer,0,sizeof(buffer));
             socklen_t len = sizeof(clientAddr);
             ret =  recvfrom(sfd,&buffer,sizeof(buffer),0,(struct sockaddr*)&clientAddr,&len);
             if(ret == 0) continue;
             printf("%s:%d say %s\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port),buffer);
        }else if(FD_ISSET(STDIN_FILENO,&rdset)){
            memset(&buffer,0,sizeof(buffer));
            int num = read(STDIN_FILENO,&buffer,sizeof(buffer));
            if(num == 0) break;
            ret = sendto(sfd,&buffer,sizeof(buffer),0,(struct sockaddr*)&clientAddr,sizeof(clientAddr));
        }
        
    }
    
    close(sfd);

    return 0;
}
//client
#include <func.h>

#define BUFFERSIZE 1024

int main()
{
    int cfd = socket(AF_INET,SOCK_DGRAM,0);
    if(cfd == -1){
        perror("socker");
    }

    struct sockaddr_in serverAddr;
    serverAddr.sin_addr.s_addr = inet_addr("192.168.44.128");
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8080);
    
    char buffer[BUFFERSIZE] = "hello server\n";

    int ret = sendto(cfd,&buffer,sizeof(buffer),0,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
    
    if(ret == -1){
        perror("sendto");
    }

    fd_set rdset;

    int maxfd = STDIN_FILENO;
    while(1){
        FD_ZERO(&rdset);
        FD_SET(cfd,&rdset);
        FD_SET(STDIN_FILENO,&rdset);
        if(cfd > maxfd) maxfd = cfd;

        select(maxfd + 1,&rdset,NULL,NULL,NULL);

        if(FD_ISSET(STDIN_FILENO,&rdset)){
            memset(&buffer,0,sizeof(buffer));
            int num = read(STDIN_FILENO,&buffer,sizeof(buffer));
            if(num == 0) break;

           ret =  sendto(cfd,&buffer,sizeof(buffer),0,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
           if(ret == -1){
               perror("sendto");
            }
        }
        if(FD_ISSET(cfd,&rdset)){
            socklen_t len = sizeof(serverAddr);
            ret = recvfrom(cfd,&buffer,sizeof(buffer),0,(struct sockaddr*)&serverAddr,&len);
            if(ret == 0){
                break;
            }

            printf("server:%s\n",buffer);
        }
    }
    close(cfd);
    return 0;
}

标签:UDP,一对一,ret,rdset,buffer,int,serverAddr,sizeof,select
From: https://www.cnblogs.com/EavenWang/p/18226183

相关文章

  • 报错信息:Invalid bound statement (not found): org.example.mapper.UserMapper.selec
    分析出现错误的原因:使用package标签加载映射sql文件,要求需要Mapper接口名称需要和映射文件相同,并且在同一个目录中。由图可见,三个位置目录及名称都一致,但是运行还是报错。经过一番折磨,最后在windows系统文件中发现我在idea里建的多层文件夹其实是一个文件夹在idea创建Direct......
  • MyBatis中insert和insertSelective的区别
    一、本文简介主要对比了MyBatis生成的Mapper类中的insert方法和insertSelective方法的区别二、insert和insertSelective的区别insert和insertSelective是MyBatis中用于插入数据到数据库的两种方法,它们之间的主要区别在于对null值的处理方式。insert:这个方法会将实体类......
  • 一对一视频直播app开发,实现跨域的多种方式
    一对一视频直播app开发,实现跨域的多种方式一、document.domain+iframe跨域此方案仅限主域相同,子域不同的跨域应用场景。实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。父窗口(http://www.demo.com/a.html))<iframeid="iframe"src="h......
  • 一对一直播软件源码,比较常用的数组排序方式有哪些?
    一对一直播软件源码,比较常用的数组排序方式有哪些?一、简单的sort排序:vararr=[1,5,3,87,23];arr.sort(function(a,b){returna-b;})console.log(arr);//输出:[1,23,3,5,87] 注:若返回b-a可获得从大到小的排序;数组的sort方法只能实现简单的按位排序,并不精......
  • ### Cause: java.sql.SQLSyntaxErrorException: Expression #4 of SELECT list is not
    最近把线上数据库备份到本地数据库进行一些代码修改时候,发现代码连接本地数据库报错,线上数据库是正常的,后来查阅了一下是SELECT列表不在GROUPBY语句内且存在不函数依赖GROUPBY语句的非聚合字段,算是比较严谨的sql模式,如果需要解决的话需要修改一下my.ini配置页面,我先去自己安装......
  • 【VTKExamples::PolyData】第五十四期 SelectVisiblePoints
    很高兴在雪易的CSDN遇见你 VTK技术爱好者QQ:870202403   公众号:VTK忠粉前言本文分享VTK样例SelectVisiblePoints,并解析接口vtkSelectVisiblePoints,希望对各位小伙伴有所帮助!感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!你的点赞就是我的动力(^U^)ノ~YO1. ......
  • udp的收发包的思考
      在测试radius性能时,想到一个问题,以前tcp报文在ip层处理时,涉及到路由查找,对于tcp协议报文;skb中没有路由缓存,没有关联的sock;且非分片报文;ip_early_demux设置为true;则调用early_demux函数提前在IP层做established状态的sock查找,并负责将sock结构体成员sk_rx_dst的路由缓存赋值......
  • 【网络】高级IO(select||poll||epoll)
    基础引入应用层read&&write的时候,把数据从用户层写到操作系统,本质是拷贝函数。read时候如果缓冲区没有数据,那么就要等待数据才能读取,因此IO=等待+拷贝,要进行拷贝,必须等待读写事件就绪。高效IO指单位时间内,IO过程中,等待的比重小,IO效率高。五种IO模型同步阻塞IO(BlockingIO......
  • css07 CSS Attribute Selectors
    https://www.w3schools.com/css/css_attribute_selectors.aspStyleHTMLElementsWithSpecificAttributesItispossibletostyleHTMLelementsthathavespecificattributesorattributevalues.CSS[attribute]SelectorThe[attribute]selectorisusedtos......
  • at-rule or selector expectedcss(css-ruleorselectorexpected)
    问题如图所示,在使用scss和less是使用//注释就会出现红色报错,这个不影响运行,但是看着很不舒服。解决没有找到什么好的解决办法,一般的解决方法是,把验证关闭,然后重启。但是后面我开启这个设置,再进行注释,没有报错,感觉还是重启的作用。先放着不管吧。......