网络编程socket套接字及其使用(六)

今天继续深入学习socket套接字的使用,上一篇文章我们主要深入介绍了如何使用套接字进行面向连接的通信编程,这里我们主要深入讲解一下基于面向非连接的编程。

对于TCP面向连接来说,在通信前,需要经过三步握手协议以建立连接,而建立连接的过程往往比较耗费时间。连接建立后,在聊天过程中,可能经过好吃一段时间,聊天的双方才会说一句话(网速比较慢的情况比较常见),那么连接是一个保存还是应先断开,等对方说话时再建立连接呢?也就是说,TCP协议的面向连接、数据确认和重传机制将会影响聊天的效率。所以我们就有必要引入另一种协议来填充这个不足缺口。目前通常采用基于UDP非连接的方式来实现。这种方式的特点是不需要建立连接,也没有数据确认和重传机制,因此实时性较高。

下面我们列举一个基于UDP的聊天列举编程进行深入透析:

  1. 服务器端代码:
     1 #include<Winsock2.h>
     2 #include<stdio.h>
     3 
     4 void main()
     5 {
     6     //load socket libariy
     7     WORD wVersionRequested;
     8     //this struct use to stored Windows Sockets value after call WSAStartup() function, 
     9     //include the data from Winscok.dll
    10     WSADATA wsaData;
    11     int err;
    12     wVersionRequested=MAKEWORD(1,1);
    13     err = WSAStartup(wVersionRequested,&wsaData);
    14     if(err!=0)
    15     {
    16         return;
    17     }
    18     if(LOBYTE(wsaData.wVersion)!=1 || (HIBYTE(wsaData.wVersion)!=1))
    19     {
    20         WSACleanup();
    21         return;
    22     }
    23     //create socket--- Protocol udp
    24     SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
    25     //Setup socket address information
    26     SOCKADDR_IN addrSrv;
    27     addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
    28     addrSrv.sin_family=AF_INET;
    29     addrSrv.sin_port=htons(6000);
    30     //binding socket with its address and port
    31     if(bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))==0)
    32     {
    33         printf("Server start...OK!\n");
    34         //data buffer;
    35         char recvBuf[100];
    36         char sendBuf[100];
    37         char tempBuf[200];
    38         //client address information
    39         SOCKADDR_IN addrClient;
    40         int len=sizeof(SOCKADDR);
    41         //endless: to receive client data
    42         while(1)
    43         {
    44             //wait data incomming
    45             recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
    46             //only receive 'q' or 'Q', stop.
    47             if(('q'==recvBuf[0])||('Q')==recvBuf[0])
    48             {
    49                 if(strlen(recvBuf)==1)
    50                 {
    51                     //chat end
    52                     sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
    53                     printf("Chat end!\n");
    54                     break;
    55                 }
    56             }
    57             //printf receive information
    58             sprintf(tempBuf,"%s: %s",inet_ntoa(addrClient.sin_addr),recvBuf);
    59             printf("%s\nserver:",tempBuf);
    60             //get input message
    61             gets(sendBuf);
    62             sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
    63         }
    64     }
    65     else
    66     {
    67         printf("Server failed start.\n");
    68     }
    69     //close socket
    70     closesocket(sockSrv);
    71     WSACleanup();
    72 }

     

  2. 客户端代码:
     1 #include<Winsock2.h>
     2 #include<stdio.h>
     3 
     4 void main()
     5 {
     6     //load socket libariy
     7     WORD wVersionRequested;
     8     //this struct use to stored Windows Sockets value after call WSAStartup() function, 
     9     //include the data from Winscok.dll
    10     WSADATA wsaData;
    11     int err;
    12     wVersionRequested=MAKEWORD(1,1);
    13     err = WSAStartup(wVersionRequested,&wsaData);
    14     if(err!=0)
    15     {
    16         return;
    17     }
    18     if(LOBYTE(wsaData.wVersion)!=1 || (HIBYTE(wsaData.wVersion)!=1))
    19     {
    20         WSACleanup();
    21         return;
    22     }
    23     //create socket--- Protocol udp
    24     SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
    25     printf("Client create....OK!\n");
    26     //define variable for server address information struct
    27     SOCKADDR_IN addrSrv;
    28     addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    29     addrSrv.sin_family=AF_INET;
    30     addrSrv.sin_port=htons(6000);
    31     //data buffer
    32     char recvBuf[100];
    33     char sendBuf[100];
    34     char tempBuf[200];
    35     int len=sizeof(SOCKADDR);
    36     //endless
    37     while(1)
    38     {
    39         printf("Client: ");
    40         gets(sendBuf);
    41         sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSrv,len);
    42         //wait response from server
    43         recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
    44         if(strlen(recvBuf)==1)
    45         {
    46             if(recvBuf[0]=='q')
    47             {
    48                 printf("chat end.\n");
    49                 break;
    50             }
    51         }
    52         sprintf(tempBuf,"%s: %s",inet_ntoa(addrSrv.sin_addr),recvBuf);
    53         printf("%s\n",tempBuf);
    54     }
    55     closesocket(sockClient);
    56     WSACleanup();
    57 }

     

  3. 程序的开头,都是需要加载套接字库。因为通信是基于UDP协议的,所以加载数据报类型的套接字(SOCK_DGRAM)。之后需要定义一个地址类型(SOCKADDR_IN)变量,用来接收返回的套接字参数。
  4. 编译运行:

End.

谢谢.

posted on 2019-11-04 11:01  Milo_lu  阅读(249)  评论(0编辑  收藏  举报

导航