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

Posted lumao1122-milolu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程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.

谢谢.

以上是关于网络编程socket套接字及其使用的主要内容,如果未能解决你的问题,请参考以下文章

Go 语言网络编程系列— Socket 编程入门:Dial 函数及其使用

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

java网络编程ServerSocket类 和Socket类的常用构造方法及其方法

Python 之 Socket编程(TCP/UDP)

深入理解TCP协议及其源代码

简单socket()编程