精华内容
下载资源
问答
  • 客户端和服务器实现全双工通信(基于线程)
    2021-05-17 14:49:47

    客户端和服务器实现全双工通信(基于线程)

    1、

    基于多线程实现一个服务器和一个客户端实现全双工通信

    服务器端创建两个线程:一个用于接收客户端发送过来的信息;一个用来给客户端发送信息。

    客户端也创建两个线程:一个用于接收服务器端发送过来的信息;一个用来给服务器端发送信息。

    2、

    示例代码

    服务器端的代码client.c

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #define SERVPORT

    3333

    #define BACKLOG

    10 //请求队列中的最大请求数

    #define MAX_CONNECTED_NO

    10 //最大是128台电脑连接

    #define MAXDATASIZE

    100

    void pthread_recv(void

    *arg);

    void Pthread_send(void *

    arg);

    int main()

    {

    struct sockaddr_in server_sockaddr,client_sockaddr;

    int sockfd,client_fd,sin_size,ret;

    pthread_t id1,id2;

    sin_size =sizeof(struct sockaddr);

    //struct sockaddr_in server_sockaddr,client_sockaddr;

    //建立一个socket连接

    //目前都是AF_INET(ipv4);SOCK_STREAM(TCP),如果是UDP,则SOCK_DGRAM

    if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){

    perror("socket");

    exit(1);

    }

    printf("socket success!,sockfd=%d\n",sockfd);

    //bind用于本地IP地址和端口的绑定

    server_sockaddr.sin_family=AF_INET;

    server_sockaddr.sin_port=htons(SERVPORT);

    server_sockaddr.sin_addr.s_addr=INADDR_ANY;

    //htonl(INADDR_ANY)

    bzero(&(server_sockaddr.sin_zero),8);

    //把本端的信息绑定

    if(bind(sockfd,(struct sockaddr

    *)&server_sockaddr,sizeof(struct

    sockaddr))==-1)

    {

    perror("bind");

    exit(1);

    }

    printf("bind success!\n");

    if(listen(sockfd,BACKLOG)==-1)

    {

    perror("listen");

    exit(1);

    }

    printf("listening....\n");

    //接受并保存客户端的信息

    if((client_fd=accept(sockfd,(struct sockaddr

    *)&client_sockaddr,&sin_size))==-1)

    {

    perror("accept");

    exit(1);

    }

    printf("client_fd=%d",client_fd);

    pthread_create(&id1,NULL,(void *)

    pthread_recv,(void*)&client_fd);

    if(ret != 0)

    perror("pthread_recv creat");

    ret=pthread_create(&id2,NULL,(void

    *)Pthread_send,(void*)&client_fd);

    if(ret != 0)

    perror("Pthread_send creat");

    pthread_join(id1,NULL);

    pthread_join(id2,NULL);

    close(sockfd);

    }

    //服务器发送线程

    void Pthread_send(void *

    arg)

    {

    int buf_len, client_fd,sendbytes;

    char buf[MAXDATASIZE];

    client_fd = *((int *)arg);

    printf("server send: ");

    while(1)

    {

    fgets(buf,MAXDATASIZE,stdin);

    buf_len =sizeof(buf);

    if((sendbytes = send(client_fd ,buf,buf_len,0))==-1)

    {

    perror("send");

    exit(1);

    }

    if(!strncmp(buf,"end",3)) //只比较字符串的前三个字符

    break;

    sleep(2);

    }

    }

    //服务器接收数据线程

    void pthread_recv(void

    *arg)

    {

    int buf_len, client_fd,recvbytes;

    char buf[MAXDATASIZE];

    client_fd = *((int *)arg);

    //接收服务端发来的信息

    while(1)

    {

    if((recvbytes = recv(client_fd ,buf,MAXDATASIZE,0))==-1)

    {

    perror("recv");

    exit(1);

    }

    else

    {

    buf[recvbytes]=0;

    printf("server received data from server is

    :%s\n",buf);

    if(!strncmp(buf,"end",3)) //只比较字符串前三个字符

    break;

    }

    sleep(1);

    }

    }

    客户端的代码:

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #define SERVPORT

    3333

    #define MAXDATASIZE

    100

    void pthread_recv(void

    *arg);

    void Pthread_send(void *

    arg);

    main(int argc,char

    *argv[]){

    int sockfd,sin_size,ret;

    struct hostent *host;

    pthread_t id1,id2;

    struct sockaddr_in

    serv_addr; //套接字的地址结构

    struct sockaddr_in server_sockaddr;

    if(argc < 2)

    {

    fprintf(stderr,"Please enter the server's hostname!\n");

    exit(1);

    }

    //AF_INET:使用的是IPV4

    //SOCK_STREAM:流式套接字

    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

    {

    perror("socket");

    exit(1);

    }

    printf("sockfd=%d\n",sockfd);

    serv_addr.sin_family=AF_INET;

    serv_addr.sin_port=htons(SERVPORT);

    //serv_addr.sin_addr=*((struct

    in_addr *)host->h_addr);

    //host->h_addr强制类型转换;建议直接使用下面的方法

    serv_addr.sin_addr.s_addr=inet_addr(argv[1]); //"127.0.0.1"); Internet地址

    bzero(&(serv_addr.sin_zero),8);

    //连接

    if(connect(sockfd,(struct sockaddr

    *)&serv_addr,sizeof(struct

    sockaddr))==-1)

    {

    perror("connect");

    exit(1);

    }

    ret=pthread_create(&id1,NULL,(void

    *)Pthread_send,(void*)&sockfd);

    if(ret != 0)

    perror("Pthread_send creat");

    pthread_create(&id2,NULL,(void *)

    pthread_recv,(void*)&sockfd);

    if(ret != 0)

    perror("pthread_recv creat");

    pthread_join(id1,NULL);

    pthread_join(id2,NULL);

    close(sockfd);

    }

    //客户端发送数据线程

    void Pthread_send(void *

    arg)

    {

    int buf_len, sockfd,sendbytes;

    char buf[MAXDATASIZE];

    sockfd = *((int *)arg);

    printf("client send: ");

    while(1)

    {

    fgets(buf,MAXDATASIZE,stdin);

    buf_len =sizeof(buf);

    if((sendbytes = send(sockfd,buf,buf_len,0))==-1)

    {

    perror("send");

    exit(1);

    }

    if(!strncmp(buf,"end",3)) //只比较字符串的前三个字符

    break;

    sleep(2);

    }

    }

    //客户端接收数据线程

    void pthread_recv(void

    *arg)

    {

    int buf_len, sockfd,recvbytes;

    char buf[MAXDATASIZE];

    sockfd = *((int *)arg);

    //接收服务端发来的信息

    while(1)

    {

    if((recvbytes = recv(sockfd,buf,MAXDATASIZE,0))==-1)

    {

    perror("recv");

    exit(1);

    }

    else

    {

    buf[recvbytes]=0;

    printf("client received data from server is :%s\n",buf);

    if(!strncmp(buf,"end",3)) //只比较字符串的前三个字符

    break;

    }

    sleep(1);

    }

    }

    2012年4月22日星期日

    更多相关内容
  • 服务器:#server.py #!/usr/bin/env python #-*-coding:utf-8-*- import sys import struct#将字符串打包为二进制流进行网络传输 import select# import signal#用于捕获中断信号 import cPickle#将python对象进行...
  • java。Tcp 全双工通信

    2018-03-21 21:44:31
    java socket tcp 全双工通信,使用多线程,使用命令行进行全双工通信
  • 全双工通信射频自干扰消除硬件实现,任宇鑫,于翠屏,本文在现有2.4GHz收发信机的基础上,针对点对点同时同频全双工通信,设计并研发了一套射频自干扰消除装置。本文设计的功率精确控制
  • 更正:我之前的两个时钟的理论是不合理的,因为全双工收发是可以共用时钟的,这个我在后面改进的主机程序中有体现。 欢迎大家测试 u8 SPI1_ReadByte(u8 TxData) { u8 retry=0; // while((SPI1->SR&1<<1>200)...
  • 基于嵌入式与单片机的485全双工通信设计实现
  • 该项目源码一两百行,测试了TCP的全双工通信,分享给大家
  • Node.js和Socket.io使全双工通信变得容易(2通,就像手机通话一样) 链接 要求 浏览器(例如Chrome) 文本编辑器(例如VS Code) 响应式 好处 仍然不需要构建工具 Node.js非阻塞事件循环支持许多并发请求 Socket....
  • PCB是第一版,调教后忘记在PCB上改了,调教后的电路声音清晰,完全实现全双工通信。使用我提供的这版PCB也不影响使用,主要是在电源地方加个电解电容;在DA输出的地方运放周边的电阻阻值,电容容值要小改一下。懂...
  • 本文主要研究HTML5 WebSockets的使用方法,它是HTML5中最强大的通信功能,定义了一个全双工通信信道,只需Web上的一个Socket即可进行通信,能减少不必要的网络流量并降低网络延迟。HTML5 WebSockets能使数据从几千...
  • 全双工通信 TCP服务器搭建,使用套接字,fork进程控制 实现双工双向通信,将文件解压放到Linux中,运行服务器,在开发板Y运行客户端
  • TCP全双工通信

    2017-07-06 14:22:59
    LabVIEW实现多上位机,单下位机的全双工TCP通讯。
  • 二、主要函数的使用要点通过建立双套接字,可以很方便地实现全双工网络通信。1.套接字建立函数:SOCKET socket(int family,int type,int protocol)对于UDP协议,写为:SOCKRET s;s=socket(AF_INET,SOCK_...

    二、主要函数的使用要点

    通过建立双套接字,可以很方便地实现全双工网络通信。

    1.套接字建立函数:

    SOCKET socket(int family,int type,int protocol)

    对于UDP协议,写为:

    SOCKRET s;

    s=socket(AF_INET,SOCK_DGRAM,0);

    或s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)

    为了建立两个套接字,必须实现地址的重复绑定,即,当一个套接字已经绑定到某本地地址后,为了让另一个套接字重复使用该地址,必须为调用bind()函数绑定第二个套接字之前,通过函数setsockopt()为该套接字设置SO_REUSEADDR套接字选项。通过函数getsockopt()可获得套接字选项设置状态。需要注意的是,两个套接字所对应的端口号不能相同。此外,还涉及到套接字缓冲区的设置问题,按规定,每个区的设置范围是:不小于512个字节,大大于8k字节,根据需要,文中选用了4k字节。

    2.套接字绑定函数

    int bind(SOCKET s,struct sockaddr_in*name,int namelen)

    s是刚才创建好的套接字,name指向描述通讯对象的结构体的指针,namelen是该结构体的长度。该结构体中的分量包括:IP地址(对应name.sin_addr.s_addr)、端口号(name.sin_port)、地址类型(name.sin_family,一般都赋成AF_INET,表示是internet地址)。

    (1)IP地址的填写方法:在全双工通信中,要把用户名对应的点分表示法地址转换成32位长整数格式的IP地址,使用inet_addr()函数。

    (2)端口号是用于表示同一台计算机不同的进程(应用程序),其分配方法有两种:1)进程可以让系统为套接字自动分配一端口号,只要在调用bind前将端口号指定为0即可。由系统自动分配的端口号位于1024~5000之间,而1~1023之间的任一TCP或UDP端口都是保留的,系统不允许任一进程使用保留端口,除非其有效用户ID是零(超级用户)。

    2)进程可为套接字指定一特定端口。这对于需要给套接字分配一众所端口的服务器是很有用的。指定范围为1024和65536之间。可任意指定。

    在本程序中,对两个套接字的端口号规定为2000和2001,前者对应发送套接字,后者对应接收套接字。

    端口号要从一个16位无符号数(u_short类型数)从主机字节顺序转换成网络字节顺序,使用htons()函数。

    根据以上两个函数,可以给出双套接字建立与绑定的程序片断。

    //设置有关的全局变量

    SOCKET sr,ss;

    HPSTR sockBufferS,sockBufferR;

    HANDLE hSendData,hReceiveData;

    DWROD dwDataSize=1024*4;

    struct sockaddr_in therel.there2;

    #DEFINE LOCAL_HOST_ADDR 200.200.200.201

    #DEFINE REMOTE_HOST-ADDR 200.200.200.202

    #DEFINE LOCAL_HOST_PORT 2000

    #DEFINE LOCAL_HOST_PORT 2001

    //套接字建立函数

    BOOL make_skt(HWND hwnd)

    {

    struct sockaddr_in here,here1;

    ss=socket(AF_INET,SOCK_DGRAM,0);

    sr=socket(AF_INET,SOCK_DGRAM,0);

    if((ss==INVALID_SOCKET)||(sr==INVALID_SOCKET))

    {

    MessageBox(hwnd,“套接字建立失败!”,“”,MB_OK);

    return(FALSE);

    }

    here.sin_family=AF_INET;

    here.sin_addr.s_addr=inet_addr(LOCAL_HOST_ADDR);

    here.sin_port=htons(LICAL_HOST_PORT);

    //another socket

    herel.sin_family=AF_INET;

    herel.sin_addr.s_addr(LOCAL_HOST_ADDR);

    herel.sin_port=htons(LOCAL_HOST_PORT1);

    SocketBuffer();//套接字缓冲区的锁定设置

    setsockopt(ss,SOL_SOCKET,SO_SNDBUF,(char FAR*)sockBufferS,dwDataSize);

    if(bind(ss,(LPSOCKADDR)&here,sizeof(here)))

    {

    MessageBox(hwnd,“发送套接字绑定失败!”,“”,MB_OK);

    return(FALSE);

    }

    setsockopt(sr SQL_SOCKET,SO_RCVBUF|SO_REUSEADDR,(char FAR*)

    sockBufferR,dwDataSize);

    if(bind(sr,(LPSOCKADDR)&here1,sizeof(here1)))

    {

    MessageBox(hwnd,“接收套接字绑定失败!”,“”,MB_OK);

    return(FALSE);

    }

    return(TRUE);

    }

    //套接字缓冲区设置

    void sockBuffer(void)

    {

    hSendData=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,dwDataSize);

    if(!hSendData)

    {

    MessageBox(hwnd,“发送套接字缓冲区定位失败!”,NULL,

    MB_OK|MB_ICONEXCLAMATION);

    return;

    }

    if((sockBufferS=GlobalLock(hSendData)==NULL)

    {

    MessageBox(hwnd,“发送套接字缓冲区锁定失败!”,NULL,

    MB_OK|MB_ICONEXCLAMATION);

    GlobalFree(hRecordData[0];

    return;

    }

    hReceiveData=globalAlloc(GMEM_MOVEABLE|GMEM_SHARE,dwDataSize);

    if(!hReceiveData)

    {

    MessageBox(hwnd,"“接收套接字缓冲区定位败!”,NULL

    MB_OK|MB_ICONEXCLAMATION);

    return;

    }

    if((sockBufferT=Globallock(hReceiveData))=NULL)

    MessageBox(hwnd,"发送套接字缓冲区锁定失败!”,NULL,

    MB_OK|MB_ICONEXCLAMATION);

    GlobalFree(hRecordData[0]);

    return;

    }

    {

    3.数据发送与接收函数;

    int sendto(SOCKET s.char*buf,int len,int flags,struct sockaddr_in to,int

    tolen);

    int recvfrom(SOCKET s.char*buf,int len,int flags,struct sockaddr_in

    fron,int*fromlen)

    其中,参数flags一般取0。

    recvfrom()函数实际上是读取sendto()函数发过来的一个数据包,当读到的数据字节少于规定接收的数目时,就把数据全部接收,并返回实际接收到的字节数;当读到的数据多于规定值时,在数据报文方式下,多余的数据将被丢弃。而在流方式下,剩余的数据由下recvfrom()读出。为了发送和接收数据,必须建立数据发送缓冲区和数据接收缓冲区。规定:IP层的一个数据报最大不超过64K(含数据报头)。当缓冲区设置得过多、过大时,常因内存不够而导致套接字建立失败。在减小缓冲区后,该错误消失。经过实验,文中选用了4K字节。

    此外,还应注意这两个函数中最后参数的写法,给sendto()的最后参数是一个整数值,而recvfrom()的则是指向一整数值的指针。

    4.套接字关闭函数:closesocket(SOCKET s)

    通讯结束时,应关闭指定的套接字,以释与之相关的资源。

    在关闭套接字时,应先对锁定的各种缓冲区加以释放。其程序片断为:

    void CloseSocket(void)

    {

    GlobalUnlock(hSendData);

    GlobalFree(hSenddata);

    GlobalUnlock(hReceiveData);

    GlobalFree(hReceiveDava);

    if(WSAAysncSelect(ss,hwnd,0,0)=SOCKET_ERROR)

    {

    MessageBos(hwnd,“发送套接字关闭失败!”,“”,MB_OK);

    return;

    }

    if(WSAAysncSelect(sr,hwnd,0,0)==SOCKET_ERROR)

    {

    MessageBox(hwnd,“接收套接字关闭失败!”,“”,MB_OK);

    return;

    }

    WSACleanup();

    closesockent(ss);

    closesockent(sr);

    return;

    }

    三、Winsock的编程特点与异步选择机制

    1 阻塞及其处理方式

    在网络通讯中,由于网络拥挤或一次发送的数据量过大等原因,经常会发生交换的数据在短时间内不能传送完,收发数据的函数因此不能返回,这种现象叫做阻塞。Winsock对有可能阻塞的函数提供了两种处理方式:阻塞和非阻塞方式。在阻塞方式下,收发数据的函数在被调用后一直要到传送完毕或者出错才能返回。在阻塞期间,被阻的函数不会断调用系统函数GetMessage()来保持消息循环的正常进行。对于非阻塞方式,函数被调用后立即返回,当传送完成后由Winsock给程序发一个事先约定好的消息。

    在编程时,应尽量使用非阻塞方式。因为在阻塞方式下,用户可能会长时间的等待过程中试图关闭程序,因为消息循环还在起作用,所以程序的窗口可能被关闭,这样当函数从Winsock的动态连接库中返回时,主程序已经从内存中删除,这显然是极其危险的。

    2 异步选择函数WSAAsyncSelect()的使用

    Winsock通过WSAAsyncSelect()自动地设置套接字处于非阻塞方式。使用WindowsSockets实现Windows网络程序设计的关键就是它提供了对网络事件基于消息的异步存取,用于注册应用程序感兴趣的网络事件。它请求Windows Sockets DLL在检测到套接字上发生的网络事件时,向窗口发送一个消息。对UDP协议,这些网络事件主要为:

    FD_READ 期望在套接字收到数据(即读准备好)时接收通知;

    FD_WRITE 期望在套接字可发送数(即写准备好)时接收通知;

    FD_CLOSE 期望在套接字关闭时接电通知

    消息变量wParam指示发生网络事件的套接字,变量1Param的低字节描述发生的网络事件,高字包含错误码。如在窗口函数的消息循环中均加一个分支:

    int ok=sizeof(SOCKADDR);

    case wMsg;

    switch(1Param)

    {

    case FD_READ:

    //套接字上读数据

    if(recvfrom(sr.lpPlayData[j],dwDataSize,0,(struct sockaddr FAR*)&there1,

    (int FAR*)&ok)==SOCKET_ERROR0

    {

    MessageBox)hwnd,“数据接收失败!”,“”,MB_OK);

    return(FALSE);

    }

    case FD_WRITE:

    //套接字上写数据

    }

    break;

    在程序的编制中,应根据需要灵活地将WSAAsyncSelect()函灵敏放在相应的消息循环之中,其它说明可参见文献[1]。此外,应该指出的是,以上程序片断中的消息框主要是为程序调试方便而设置的,而在正式产品中不再出现。同时,按照程序容错误设计,应建立一个专门的容错处理函数。程序中可能出现的各种错误都将由该函数进行处理,依据错误的危害程度不同,建立几种不同的处理措施。这样,才能保证双方通话的顺利和可靠。

    四、结论

    本文是多媒体网络传输项目的重要内容之一,目前,结合硬件全双工语音卡等设备,已经成功地实现了话音的全双工的通信。

    展开全文
  • 针对现有全双工通信MAC协议静态配对的不足,本文提出一种动态自配对MAC协议设计方案。该方案能够增大全双工无线通信的建立几率,避免通信冲突,提升频带利用率。仿真结果表明,与传统的半双工无线通信进行比较,动态...
  • 一文了解websocket全双工通信java实现

    1.websocket介绍

    WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
    WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    1.1注解介绍

    @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。
    注解的值将被用于监听用户连接的终端访问URL地址。
    @OnMessage 前端发送消息 进行处理
    @OnClose  关闭处理
    @OnOpen  前端打开页面的处理
    
    

    2.demo

    引入依赖:

    compile group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.5.5'
    
    

    2.1 后端代码

    package com.zqm.utils.socket;
    
    /**
     * @describe: sid 需要提前约定
     * @author:zqm
     */
    
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.stereotype.Component;
    
    import javax.websocket.OnClose;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.concurrent.ConcurrentHashMap;
    
    @ServerEndpoint("/websocket/{sid}")
    @Component
    public class WebSocketTest {
    
        private static final ConcurrentHashMap<String, Session> SESSION_MAP = new ConcurrentHashMap();
    
        /**
         * 接受消息
         * @param sid
         * @param session
         * @throws IOException
         * @throws InterruptedException
    
        //    @OnMessage
        //    public void onMessage(@PathVariable("sid") String sid, Session session)
        //            throws IOException, InterruptedException {
        //        System.out.println();
        //    }
         */
    
        /**
         * 接受消息
         *
         * @param message 客户端发送的消息
         * @param session
         * @throws IOException
         * @throws InterruptedException
         */
    
        @OnMessage
        public void onMessage(String message, Session session) {
            System.out.println(session.getPathParameters().get("sid"));
            System.out.println(message);
        }
    
        /**
         * 登记连接
         *
         * @param sid
         * @param session
         */
        @OnOpen
        public void onOpen(@PathParam("sid") String sid, Session session) {
            if (SESSION_MAP.containsKey(sid)) {
                return;
            }
            SESSION_MAP.put(sid, session);
            System.out.println("Client connected");
        }
    
    
        /**
         * 注销连接
         */
       c
        public void onClose() {
            System.out.println("Connection closed");
        }
    
    
        public void sendMessage(String sid, String message) throws IOException {
            if (StringUtils.isNotBlank(sid)) {
                Session session = SESSION_MAP.get(sid);
                session.getBasicRemote().sendText(message);
            }
    
        }
    }
    
    
    package com.zqm.controller;
    
    import com.zqm.utils.socket.WebSocketTest;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.io.IOException;
    
    /**
     * @describe:
     * @author:zqm
     */
    @RestController
    @RequestMapping("web-socket")
    public class WebSocketController {
    
        @Autowired
        private WebSocketTest webSocketTest;
    
        @RequestMapping("send")
        public void sendMessage(String message) throws IOException {
            webSocketTest.sendMessage("user000",message);
        }
    }
    
    

    2.2 前端代码

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            Websocket Demo <br />
            <input id="text" type="text" /> 
            <button onclick="send()"> Send </button>   
            <button   onclick="closeWebSocket()"> Close </button>
            <div id="message">   </div>
            
        <script type="text/javascript">
         //判断当前浏览器是否支持WebSocket
          if('WebSocket' in window){
              websocket = new WebSocket("ws://192.168.43.12:8081/zqm/websocket/user");
              console.log("link success")
          }else{
              alert('Not support websocket')
          }
          
          //连接发生错误的回调方法
          websocket.onerror = function(){
              setMessageInnerHTML("error");
          };
           
          //连接成功建立的回调方法
          websocket.onopen = function(event){
              setMessageInnerHTML("open");
          }
           console.log("-----")
          //接收到消息的回调方法
          websocket.onmessage = function(event){
                setMessageInnerHTML(event.data);
          }
           
          //连接关闭的回调方法
          websocket.onclose = function(){
              setMessageInnerHTML("close");
          }
           
          //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
          window.onbeforeunload = function(){
              websocket.close();
          }
           
          //将消息显示在网页上
          function setMessageInnerHTML(innerHTML){
              document.getElementById('message').innerHTML += innerHTML + '<br/>';
          }
           
          //关闭连接
          function closeWebSocket(){
              websocket.close();
          }
           
          //发送消息
          function send(){
              var message = document.getElementById('text').value;
              websocket.send(message);
          }
        </script>
            
        </body>
    </html>
    

    2.3 效果

    1.先启动后端服务,打开html,显示连接成功
    在这里插入图片描述
    2.客户端发送消息,后台接受成功
    在这里插入图片描述

    3.后台发送消息,客户端接受成功
    在这里插入图片描述

    展开全文
  • 一、WebSocket简介WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,...

    一、WebSocket简介

    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

    WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

    二、WebSocket 通信原理

    为了实现 WebSocket 通信,在 HTTP 连接建立之后,需要完成一 次“握手”(Handshaking)的步骤。

    握手·请求

    为了实现 WebSocket 通信,需要用到 HTTP 的 Upgrade 首部字 段,告知服务器通信协议发生改变,以达到握手的目的。

    ad38fd855a85

    请求.jpg

    Sec-WebSocket-Key 字段内记录着握手过程中必不可少的键值。 Sec-WebSocket-Protocol 字段内记录使用的子协议。 子协议按 WebSocket 协议标准在连接分开使用时,定义那些连接 的名称。

    177 握手·响应

    对于之前的请求,返回状态码 101 Switching Protocols 的响应。

    ad38fd855a85

    响应.jpg

    Sec-WebSocket-Accept 的字段值是由握手请求中的 SecWebSocket-Key 的字段值生成的。 成功握手确立 WebSocket 连接之后,通信时不再使用 HTTP 的数 据帧,而采用 WebSocket 独立的数据帧。

    成功握手确立 WebSocket 连接之后,通信时不再使用 HTTP 的数 据帧,而采用 WebSocket 独立的数据帧。

    ad38fd855a85

    通信原理图.jpg

    JavaScript 可调用“The WebSocket API”,以下为调用 WebSocket API,每 50ms 发送一次数据的实例。

    var socket = new WebSocket('ws://game.example.com:12010/updates');

    socket.onopen = function () {

    setInterval(function() {

    if (socket.bufferedAmount == 0)

    socket.send(getUpdateData());

    }, 50);

    };

    展开全文
  • 485全双工通信

    2010-10-10 12:59:01
    485全双工通信
  • 下面来看看一看这个认证的工作过程:第一步: 客户端发送http request 给服务器,服务器验证该用户是否已经登录验证过了,如果没有的话,服务器会返回一个401 Unauthozied给客户端,并且在Response 的 header ...
  • 485全双工通信.zip

    2022-01-14 22:54:41
    485全双工通信.zip
  • 针对实时型相机对系统小型化、通用化及数据高速率可靠传输的需求,文中在研究高速串行器/解串器(SerDes)器件TLK2711工作原理的基础上,提出了高速串行全双工通信协议总体设计方案。文章以TLK2711为物理层、FPGA为...
  • PC机与PIC单片机串行全双工通信.docx
  • 客户端: public class MyChatClient { public static void main(String[] args) { try { InetAddress localHost = InetAddress.getLocalHost(); String hostAddress = localHost.getHostAddress();...
  • 51单片机的485全双工通信程序,程序简明,适合初学者使用
  • 全双工通信是什么意思?

    千次阅读 2020-11-18 10:39:51
    RS-422标准就是全双工通信标准。双工(Full Duplex)是 在微处理器与外围设备之间采用发送线和接受线各自独立的方法,可以使数据在两个方向上同时进行传送操作。指在发送数据的同时也能够接收数据,两者同步进行,...
  • 本文针对电容耦合功率传输系统,提出了一种在共享信道上具有全双工通信的新型无线功率传输系统。 为了分析功率和信号传输,建立了功率和信号通道的频域模型。 基于该模型,分析了信道的信号传输特性以及功率流对信号...
  • 全双工通信的频谱有效双向解码转发中继
  • while True: msg=input("Python全双工通信测试,请输入发送信息:") tcpCliSock.send(msg.encode('utf-8')) ''' while True: data = tcpCliSock.recv(BUFSIZ) if not data: break #tcpCliSock.send('[%s] %s' %...
  • 这是一个使用 node.js 编写的全双工通信聊天室,会话大厅已经完成,私聊 room 的细节还未完善,有空会继续编写。相关技术逻辑请查阅 体验成品小样: 部署步骤: 通过 安装生产环境 $ npm i 启动服务器 $ node server...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,112
精华内容 29,244
关键字:

全双工通信

友情链接: 数字图像处理.rar