zoukankan      html  css  js  c++  java
  • 网络编程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!
      ");
      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!
      ");
      54                     break;
      55                 }
      56             }
      57             //printf receive information
      58             sprintf(tempBuf,"%s: %s",inet_ntoa(addrClient.sin_addr),recvBuf);
      59             printf("%s
      server:",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.
      ");
      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!
      ");
      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.
      ");
      49                 break;
      50             }
      51         }
      52         sprintf(tempBuf,"%s: %s",inet_ntoa(addrSrv.sin_addr),recvBuf);
      53         printf("%s
      ",tempBuf);
      54     }
      55     closesocket(sockClient);
      56     WSACleanup();
      57 }
    3. 程序的开头,都是需要加载套接字库。因为通信是基于UDP协议的,所以加载数据报类型的套接字(SOCK_DGRAM)。之后需要定义一个地址类型(SOCKADDR_IN)变量,用来接收返回的套接字参数。
    4. 编译运行:

    End.

    谢谢.

  • 相关阅读:
    CentOS 6.x 系统安装选项说明
    MySQL表的操作
    6月13号
    6月11号
    6月10号
    6月9号
    6月6
    day27
    day 28
    day 29
  • 原文地址:https://www.cnblogs.com/lumao1122-Milolu/p/11791023.html
Copyright © 2011-2022 走看看