首页 > 编程语言 >0915,SOCKET网络编程部分,三种I/O多路复用模型(select ,poll,epoll)

0915,SOCKET网络编程部分,三种I/O多路复用模型(select ,poll,epoll)

时间:2024-09-20 21:23:20浏览次数:10  
标签:std SOCKET epoll int listenfd seraddr 0915 using include

目录   nc 127.0.0.1 port

01_socket_client.cc

01_socket_server.cc

02_select_client.cc

02_select_server.cc

03_poll_server.cc

04_epoll_server.cc

01_socket_client.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;


int main(int argc,char** argv)
{
    //socket-->listenfd
    int listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0){error(1,errno,"socket");}

    //sockaddr_in --> connect
    struct sockaddr_in seraddr;
    memset(&seraddr,0,sizeof(seraddr));
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(atoi(argv[2]));//port
    seraddr.sin_addr.s_addr=inet_addr(argv[1]);//ip
    int ret=connect(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
    if(ret<0){error(1,errno,"connect");}

    //三次握手建立成功

    while(1){
        cout<<"propose send message to server"<<endl;
        string line;
        getline(std::cin,line);

        ret=send(listenfd,line.data(),line.size(),0);
        if(ret<0){
            cout<<"send error"<<endl;
        }else if(ret==0){
            cout<<"ret==0"<<endl;
        }else{
            cout<<"send sucessfully"<<endl;
        }

        char buff[128]={0};
        ret=recv(listenfd,buff,sizeof(buff),0);
        if(ret<0){
            cout<<"recv error"<<endl;
        }else if(ret==0){
            cout<<"ret==0"<<endl;
        }else{
            cout<<"recv sucessfully>>>"<<buff<<endl;
        }

    }
    close(listenfd);

    return 0;
}

01_socket_server.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;


int main(int argc,char** argv)
{

    int listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0){error(1,errno,"socket");}

    //port ip 复用
    int opt=1;
    int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
                       sizeof(opt));
    if(retval<0){error(1,errno,"setscockopt");}
    int opt2=1;
    retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
                       sizeof(opt2));
    if(retval<0){error(1,errno,"setscockopt2");}

    //bind
    struct sockaddr_in seraddr;
    memset(&seraddr,0,sizeof(seraddr));
    seraddr.sin_addr.s_addr=inet_addr(argv[1]);
    seraddr.sin_port=htons(atoi(argv[2]));
    seraddr.sin_family=AF_INET;
    int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
    if(ret<0){error(1,errno,"bind");}

    //监听
    ret=listen(listenfd,128);
    if(ret<0){error(1,errno,"listen");}
    cout<<"server is listen"<<endl;


    //从listenfd队列中取下一个peerfd
    int connfd=accept(listenfd,nullptr,nullptr);
    if(connfd<0){error(1,errno,"accept");}

    //三次握手建立成功
    
    while(1){
        char buff[128]={0};
        ret=recv(connfd,buff,sizeof(buff),0);
        if(ret<0){
            cout<<"recv error"<<endl;
        }else if(ret==0){
            cout<<"ret==0"<<endl;
        }else{
            cout<<"recv sucessfully>>>"<<buff<<endl;
        }

        cout<<"propose send message to client"<<endl;
        string line;
        getline(std::cin,line);

        int ret1=send(connfd,line.data(),line.size(),0);
        if(ret1<0){
            cout<<"send error"<<endl;
        }else if(ret1==0){
            cout<<"ret1==0"<<endl;
        }else{
            cout<<"send sucessfully"<<endl;
        }

    }

    close(listenfd);
    close(connfd);


    return 0;
}

02_select_client.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>

#include <iostream>
#include <string>

#define SERV_IP "192.168.235.128"
#define SERV_PORT 8000

using std::cout;
using std::endl;
using std::string;


int main(int argc,char** argv)
{
    //socket-->listenfd
    int listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0){error(1,errno,"socket");}

    //sockaddr_in --> connect
    struct sockaddr_in seraddr;
    memset(&seraddr,0,sizeof(seraddr));
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(SERV_PORT);//port
    /* seraddr.sin_addr.s_addr=inet_addr(SERV_IP);//ip */
    /* inet_pton(listenfd, SERV_IP, &serv_addr.sin_addr.s_addr); */
    seraddr.sin_addr.s_addr=htonl(INADDR_ANY);//服务器绑定所有可用接口
    int ret=connect(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
    if(ret<0){error(1,errno,"connect");}

    //三次握手建立成功

    char buff[BUFSIZ];//标准io操作的缓冲区大小
    int nByte;
    while(1){
        fgets(buff,sizeof(buff),stdin);//helloc-->hello\n\0
        write(listenfd,buff,strlen(buff));//buff有效长度
        //buff的内容写入listenfd(套接字本质文件描述符)

        nByte=read(listenfd,buff,sizeof(buff));
        //读取服务器的响应,nByte实际读取的字节数
        
        write(STDOUT_FILENO,buff,nByte);
        //写到stdout
    }
    close(listenfd);

    return 0;
}

02_select_server.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>
#include <sys/select.h>
#include <sys/time.h>

#include <iostream>
#include <string>

#define SERV_PORT 8000

using std::cout;
using std::endl;
using std::string;


int main(int argc,char** argv)
{
            int cnt ;//debug

    int connfd,sockfd;
    int listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0){error(1,errno,"socket");}

    //port ip 复用
    int opt=1;
    int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
                       sizeof(opt));
    if(retval<0){error(1,errno,"setscockopt");}
    int opt2=1;
    retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
                       sizeof(opt2));
    if(retval<0){error(1,errno,"setscockopt2");}

    //bind
    struct sockaddr_in seraddr;
    bzero(&seraddr,sizeof(seraddr));/* memset(&seraddr,0,sizeof(seraddr)); */
    seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
    seraddr.sin_port=htons(SERV_PORT);
    seraddr.sin_family=AF_INET;
    int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
    if(ret<0){error(1,errno,"bind");}

    //监听
    ret=listen(listenfd,128);
    if(ret<0){error(1,errno,"listen");}
    cout<<"server is listen"<<endl;


    //三次握手建立成功
    
    char buff[BUFSIZ],str[BUFSIZ];

    int maxfd=listenfd;
    int maxi=-1;
    fd_set rset,allset;
    int client[FD_SETSIZE];//多1024,可以监视的最大文件描述符数量
                           //定义在/usr/include/linux/posix_types.h

    for(int i=0;i<FD_SETSIZE;++i){
        client[i]=-1;
    }
    FD_ZERO(&allset);
    FD_SET(listenfd,&allset);

    while(1){
        rset=allset;
        int nready=select(maxfd+1,&rset,NULL,NULL,NULL);
        //nready就绪的描述符数量
        if(nready<0){error(1,errno,"select");}

        //01,监听到listenfd 新的链接进来
        if(FD_ISSET(listenfd,&rset)){
            struct sockaddr_in clie_addr;
            socklen_t clie_addr_len=sizeof(clie_addr);

            //新连接的套接字
            connfd=accept(listenfd,(struct sockaddr*)&clie_addr,
                          &clie_addr_len);
            if(connfd==-1){error(1,errno,"accept");}

            printf("receive from %s : %d\n",
                   inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),
                   ntohs(clie_addr.sin_port));

            //三次握手成功

            int i;
            for(i=0;i<FD_SETSIZE;++i){
                if(client[i]<0){
                    client[i]=connfd;
                    break;//加入监听数组
                } 
            }

//==============================
            cout<<cnt++<<"  "<<i<<endl;
            if(i==FD_SETSIZE){
                fputs("too much client\n",stderr);
                exit(1);
            }
            FD_SET(connfd,&allset);//添加新连接

            //更新maxi,maxfd
            if(connfd>maxfd){
                maxfd=connfd;
            }
            if(i>maxi){
                maxi=i;
            }

            //如果nready=1.继续while循环,不用走下面的for循环
            if(--nready==0){
                continue;
            }
        }

        //02遍历client数组,元素为正,被监听到
        //是老连接,可以进行数据发送接受
        for(int i=0;i<=maxi;++i){//caution:i<=maxi
            if((sockfd=client[i])<0){
                continue;
            }
//==============================
            cout<<cnt++<<"  "<<sockfd<<endl;
            if(FD_ISSET(sockfd,&rset)){
                int nByte=read(sockfd,buff,sizeof(buff));
                if(nByte==0){
                    //数据读完了,(缓冲区没有数据
                    //连接要断开了
                    close(sockfd);
                    cout<<"client "<<sockfd<<" closed connection\n"<<endl;
                    FD_CLR(sockfd,&allset);
                    client[i]=-1;
                }else if(nByte>0){
                    for(int j=0;j<nByte;++j){
                        buff[j]=toupper(buff[j]);//a->A
                    }
                    write(sockfd,buff,nByte);
                    write(STDOUT_FILENO,buff,nByte);
                }
                if(--nready==0){
                    break;
                }
            }
        }


    }

    close(listenfd);
    close(connfd);


    return 0;
}

03_poll_server.cc

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#include <iostream>
#include <string>

#define OPEN_MAX 1024
/* #define SERV_IP "192.168.235.128" */
#define SERV_IP "127.0.0.1"
#define SERV_PORT 7888

using std::cout;
using std::endl;
using std::string;


/* struct pollfd */
/* { */
/*     int   fd;       //要监听的文件描述符 */
/*     short events;   //待监听的文件描述符的事件 POLLIN/POLLOUT/POLLERR */
/*     short revents;  //revents & POLLIN */
/* }; */

int main(int argc,char** argv)
{
            int cnt ;//debug

    int connfd,sockfd;
    int listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0){error(1,errno,"socket");}

    //port ip 复用
    int opt=1;
    int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
                       sizeof(opt));
    if(retval<0){error(1,errno,"setscockopt");}
    int opt2=1;
    retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
                       sizeof(opt2));
    if(retval<0){error(1,errno,"setscockopt2");}

    //bind
    struct sockaddr_in seraddr;
    bzero(&seraddr,sizeof(seraddr));/* memset(&seraddr,0,sizeof(seraddr)); */
    seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
    /* seraddr.sin_addr.s_addr=inet_pton( */
    /*        listenfd, SERV_IP, &seraddr.sin_addr.s_addr); */
    seraddr.sin_port=htons(SERV_PORT);
    seraddr.sin_family=AF_INET;

    int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
    if(ret<0){error(1,errno,"bind");}

    //监听
    ret=listen(listenfd,128);
    if(ret<0){error(1,errno,"listen");}
    cout<<"server is listen"<<endl;


    //三次握手建立成功
    
    char buff[BUFSIZ],str[INET_ADDRSTRLEN];
                     //IPV4地址的字符串表示形式的最大长度

    int maxi=0;
    struct pollfd client[OPEN_MAX];
    //FOPEN_MAX:一个程序可以同时打开的最大文件流数量

    //poll类型,listenfd加入监听
    client[0].fd=listenfd;
    client[0].events=POLLIN;

    for(int i=1;i<OPEN_MAX;++i){//i=0,会把listenfd删掉,注意初始化顺序
        client[i].fd=-1;
    }


    while(1){

        int nready=poll(client,maxi+1,-1);
        if(nready<0){error(1,errno,"select");}
//==============================
            cout<<cnt++<<"  "<<client[0].fd<<endl;

        //01,监听到listenfd 新的链接进来
        if(client[0].revents & POLLIN){
            struct sockaddr_in clie_addr;
            socklen_t clie_addr_len=sizeof(clie_addr);

            //新连接的套接字
            connfd=accept(listenfd,(struct sockaddr*)&clie_addr,
                          &clie_addr_len);
            if(connfd==-1){error(1,errno,"accept");}

            printf("receive from %s : %d\n",
                   inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),
                   ntohs(clie_addr.sin_port));

            //三次握手成功

            int i;
            for(i=1;i<OPEN_MAX;++i){
                if(client[i].fd<0){
                    client[i].fd=connfd;
                    break;//加入监听数组
                } 
            }
            client[i].events=POLLIN;
            //设置要监听的类型

            if(i==OPEN_MAX){
                fputs("too much client\n",stderr);
                exit(1);
            }

            //更新maxi,fd有新增
            if(i>maxi){
                maxi=i;
            }

            //如果nready=1.继续while循环,不用走下面的for循环
            if(--nready==0){
                continue;
            }
        }

        //02遍历client数组,元素为正,被监听到
        //是老连接,可以进行数据发送接受
        for(int i=0;i<=maxi;++i){//caution:i<=maxi
            if((sockfd=client[i].fd)<0){
                continue;
            }

            //老连接上有数据
            if(client[i].revents & POLLIN){
                int nByte=read(sockfd,buff,sizeof(buff));
                if(nByte<0){
                    if(errno==ECONNRESET){//客户端被强制关闭
                        cout<<"client ["<<i<<"] abort connect"<<endl;
                        close(sockfd);
                        client[i].fd=-1;
                    }else{
                        perror("read nByte=0 error");
                    }
                }else if(nByte>0){
                    for(int j=0;j<nByte;++j){
                        buff[j]=toupper(buff[j]);//a->A
                    }
                    write(sockfd,buff,nByte);
                    write(STDOUT_FILENO,buff,nByte);
                }else{
                    close(sockfd);
                    cout<<"client ["<<i<<"] closed connection"<<endl;
                    client[i].fd=-1;
                }

                if(--nready==0){
                    break;
                }
            }
        }


    }

    close(listenfd);
    close(connfd);


    return 0;
}

04_epoll_server.cc

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#include <iostream>
#include <string>

#define OPEN_MAX 1024
/* #define SERV_IP "192.168.235.128" */
#define SERV_IP "127.0.0.1"
#define SERV_PORT 6888

using std::cout;
using std::endl;
using std::string;

/* typedef union epoll_data { */
/*     void        *ptr; */
/*     int          fd; */
/*     uint32_t     u32; */
/*     uint64_t     u64; */
/* } epoll_data_t; */

/* struct epoll_event { */
/*     uint32_t     events; //EPOLLIN/EPOLLOUT/EPOLLERR */
/*     epoll_data_t data;        /1* User data variable *1/ */
/* }; */


int main(int argc,char** argv)
{
            int cnt ;//debug

    int connfd,sockfd;
    int listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0){error(1,errno,"socket");}

    //port ip 复用
    int opt=1;
    int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
                          sizeof(opt));
    if(retval<0){error(1,errno,"setscockopt");}
    int opt2=1;
    retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
                      sizeof(opt2));
    if(retval<0){error(1,errno,"setscockopt2");}

    //bind
    struct sockaddr_in seraddr;
    bzero(&seraddr,sizeof(seraddr));
    seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
    /* seraddr.sin_addr.s_addr=inet_pton( */
    /*        listenfd, SERV_IP, &seraddr.sin_addr.s_addr); */
    seraddr.sin_port=htons(SERV_PORT);
    seraddr.sin_family=AF_INET;

    int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
    if(ret<0){error(1,errno,"bind");}

    //监听
    ret=listen(listenfd,128);
    if(ret<0){error(1,errno,"listen");}
    cout<<"server is listen"<<endl;




    char buff[BUFSIZ],str[INET_ADDRSTRLEN];
    //IPV4地址的字符串表示形式的最大长度

    //创建红黑树的根节点(红黑树+就绪链表)
    int epfd=epoll_create(OPEN_MAX);
    /* int epfd=epoll_create1(1); */
    if(epfd==-1){error(1,errno,"epoll_create1");}

    //赋值evt,listenfd加入监听
    struct epoll_event evt,ep[OPEN_MAX];
    evt.events=EPOLLIN;
    evt.data.fd=listenfd;
    ret=epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&evt);
    if(ret<0){error(1,errno,"epoll_ctl(add) listenfd");}


    while(1){

        int nready=epoll_wait(epfd,ep,OPEN_MAX,-1);
        if(nready<0){error(1,errno,"select");}
//==============================
cout<<cnt++<<"  "<<ep[0].data.fd<<endl;
//递增的ep[0].data.fd,记录的是接收到的事件的数量
//这个上下文中是用来输出当前处理的事件的文件描述符,
//可能会是新连接的文件描述符,所以会看起来是递增的                    


        //02遍历nready
        for(int i=0;i<nready;++i){
            //异常处理
            if(!(ep[i].events & EPOLLIN)){
                continue;
            }

            //监听到listenfd,新连接
            //(监听到连接事件)
            if(ep[i].data.fd == listenfd){

                struct sockaddr_in clie_addr;
                socklen_t clie_addr_len=sizeof(clie_addr);

                //新连接的套接字
                connfd=accept(listenfd,(struct sockaddr*)&clie_addr,
                              &clie_addr_len);
                if(connfd==-1){error(1,errno,"accept");}

                printf("receive from %s : %d\n",
                       inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),
                       ntohs(clie_addr.sin_port));

                //三次握手成功

                //新连接加入监听
                evt.events=EPOLLIN;
                evt.data.fd=connfd;
                ret=epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&evt);
                if(ret<0){error(1,errno,"epoll_ctl(add) connfd");}
            }
            //不是连接事件--> 读写事件-->有消息
            else {
                sockfd=ep[i].data.fd;
                int nByte=read(sockfd,buff,sizeof(buff));

                //缓冲区空,即将断开
                if(nByte==0){
                    ret=epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);
                    if(ret<0){error(1,errno,"epoll_ctl(delete)");}
                    close(sockfd);
                    cout<<"client ["<<sockfd<<"] closed connecttion"<<endl;
                }
                //连接异常
                else if(nByte<0){
                    perror("epoll_wait error");
                    ret=epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);
                    if(ret<0){error(1,errno,"epoll_ctl(delete)");}
                    close(sockfd);
                }
                //正常通信
                else{
                    for(int j=0;j<nByte;++j){
                        buff[j]=toupper(buff[j]);//a->A
                    }
                    write(sockfd,buff,nByte);
                    write(STDOUT_FILENO,buff,nByte);
                }
            }
        }
    }

    close(listenfd);
    close(connfd);


    return 0;
}

标签:std,SOCKET,epoll,int,listenfd,seraddr,0915,using,include
From: https://blog.csdn.net/qq_51583806/article/details/142371169

相关文章

  • torch.distributed.DistNetworkError: The server socket has failed to listen on an
    解决方案是在torchrun中添加参数--master_port改变masterport。且注意这个参数一定要加在要跑的文件即src/entry_point/train.py之前,否则会被忽略。引用:https://juejin.cn/post/7260668104752775228我的代码是:torchrun--nproc_per_node1--master_port29501-mtraining.......
  • Websocket防护的重要性及应对策略:快快网络专家团队的创新实践
    WebSocket(WSS)因其双向和全双工通信的特点,在现代网络通信中得到广泛应用,尤其是在需要低延迟和实时数据交互的场景中。然而,随着WebSocket的普及,其安全性问题也日益凸显,各种针对WSS的攻击手段层出不穷,给企业的数据安全带来了严峻的挑战。针对WSS的攻击具有多样性和隐蔽性。其中,最......
  • # 利刃出鞘_Tomcat 核心原理解析(十一)-- Tomcat 附加功能 WebSocket -- 3
    利刃出鞘_Tomcat核心原理解析(十一)--Tomcat附加功能WebSocket–3一、Tomcat专题-WebSocket-案例-OnMessage分析1、WebSocketDEMO案例实现流程分析:OnMessage分析2、在项目dzs168_chat_room中,在websocket类ChatSocket.java中,创建publicvoidonMes......
  • Can't connect to local MySQL server through socket
    mysql-urootERROR2002(HY000):Can'tconnecttolocalMySQLserverthroughsocket'/tmp/mysql.sock'(2)这是mysql登录时找不到套接字的问题。首先需要明白的是,Linux端的mysqlserver启动时会开启一个socket,Linux上的MySQL的客户端在不使用IP连接时mysqlserver时,默认......
  • C#实现Socket客户端
    usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;u......
  • C++基于select和epoll的TCP服务器
    select版本服务器#include<arpa/inet.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<unistd.h>#include<sys/socket.h>#include<string>#include<pthread.h>#include<sys/select.h>......
  • 【Linux】多路转接epoll
    一、I/O多路转接poll1.1poll函数接口函数原型函数参数fds:是一个poll函数监听的结构列表,每一个元素中包含了三部分内容:文件描述符,监听的事件集合,返回的事件集合。nfds:表示的是fds数组的长度timeout:表示poll函数的超时时间,单位是毫秒函数功能       poll函数用......
  • Netty WebSocket 最简单的聊天室
    Netty最为后端服务处理WebSocket协议连接后端代码pom.xml<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xs......
  • Java结合WebSocket 实现简单实时双人协同 pk 答题
    引入实现过程WebSocket后端1、实体类2、异常处理类3、游戏状态枚举类4、ws主类5、配置类及工具类引入引入与技术选型:在实时互动应用中,实现流畅的多人协同对战功能是一大挑战。WebSocket技术,以其全双工通信能力,提供了解决方案。不同于传统HTTP请求的短连接,WebSocket建立持久连接,极......
  • HTML页面中搭建WebSocket服务和调试部署的手把手操作教程
    好的,以下是一份关于“在HTML页面中搭建WebSocket服务和调试部署”的手把手操作流程,由浅入深,先整体后分部:一、引言WebSocket是一种在单个TCP连接上进行全双工通信的协议。它允许服务器主动发送信息给客户端,使得实时应用成为可能。本文将详细介绍如何在HTML页面中搭建WebSoc......