UDP服务器简朴素现(C)

打印 上一主题 下一主题

主题 886|帖子 886|积分 2662

        UDP客户端搭建过程
        1、加载库
        2、创建socket套接字
          3、绑定地址IP
        4、收发数据
        5、关闭套接字
        6、卸载库
  一、加载库

        要用到Winsock2库里的WSAStartup函数,须要包罗相应的头文件。函数的返回值是一个整型,通过检察VS官方资助文档,我们判定加载库是否乐成。代码如下:
  1. //加载库
  2.     WORD wVersionRequested;
  3.     WSADATA wsaData;
  4.     int err;
  5.     /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
  6.     wVersionRequested = MAKEWORD(2, 2);
  7.     err = WSAStartup(wVersionRequested, &wsaData);
  8.     if (err != 0) {
  9.         /* Tell the user that we could not find a usable */
  10.         /* Winsock DLL.                                  */
  11.         printf("WSAStartup failed with error: %d\n", err);
  12.         return 1;
  13.     }
  14.     /* Confirm that the WinSock DLL supports 2.2.*/
  15.     /* Note that if the DLL supports versions greater    */
  16.     /* than 2.2 in addition to 2.2, it will still return */
  17.     /* 2.2 in wVersion since that is the version we      */
  18.     /* requested.                                        */
  19.     if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
  20.         /* Tell the user that we could not find a usable */
  21.         /* WinSock DLL.                                  */
  22.         printf("Could not find a usable version of Winsock.dll\n");
  23.         WSACleanup();
  24.         return 1;
  25.     }
  26.     else
  27.         printf("The Winsock 2.2 dll was found okay\n");
复制代码
二、创建套接字

        创建套接字须要使用socket函数。函数的3个参数,分别代表 地址族,套接字范例,通讯协议。根据返回值是否为非常,来判定套接字创建是否乐成。若创建失败,须要卸载库,并终止运行。代码如下:
  1. SOCKET socklisten = socket(AF_INET,SOCK_DGRAM,0);
  2.     if(socklisten == INVALID_SOCKET){
  3.         printf("socket err\n");
  4.         WSACleanup();
  5.         return 1;
  6.     }
复制代码
三、绑定地址信息(IP)

        绑定IP地址使用的函数是bind函数。函数的返回值是一个整型,根据函数的返回值来判定IP绑定是否乐成,失败返回SOCKET_ERROR,此时不但要卸载库,还要关闭套接字。
        为了方便设置端标语和IP,我们使用sockaddr_in,传入函数时,再逼迫范例转换将其地址转换为sockaddr*范例。
  1. //绑定地址信息
  2.     sockaddr_in addrserver;
  3.     addrserver.sin_family = AF_INET;
  4.     addrserver.sin_addr.S_un.S_addr=0;
  5.     addrserver.sin_port = htons(8899);//设置端口号,并转换网络字节序
  6.     if(SOCKET_ERROR == bind(socklisten,(const struct sockaddr*)&addrserver,sizeof(addrserver))){
  7.         printf("bind err\n");
  8.         closesocket(socklisten);
  9.         WSACleanup();
  10.         return 1;
  11.     }
复制代码
四、吸收与发送信息

           吸收消息使用recvfrom函数。函数含6个参数,分别是:界说的套接字;输出参数,字符串范例,用来存放收到的消息;字符串长度;标志位(填0即可);输出参数,是sockaddr范例的布局体指针,表现消息的泉源;消息泉源布局体的长度的地址。
  若能正常吸收,则返回值>0;假如连接关闭,则返回0,假如吸收非常返回错误信息。
在能正常收到消息的情况下,我们打印对端IP地址 和 用来存放消息的字符串即消息内容。这里我们使用 inet_ntoa函数将ulong型IP表现转换为十进制字符串四等分型IP表现。
           发送消息使用sendto函数,函数含6个参数,分别是:上述套接字;字符串,用来存放发送内容;字符串的长度;标志位,填0即可;客户端的地址;客户端的大小
  1. //接收数据recvfrom
  2.     char szbuf[1024]={0};
  3.     sockaddr_in addrclient;
  4.     int nsize = sizeof(addrclient);
  5.     while(1)
  6.     {
  7.         int nreadnum = recvfrom(socklisten,szbuf,sizeof(szbuf),0,(struct sockaddr*)&addrclient,&nsize);
  8.         if(nreadnum >0)
  9.         {
  10.             printf("%s say: %s\n",inet_ntoa(addrclient.sin_addr),szbuf);
  11.             scanf_s("%s",szbuf);
  12.             //发送数据
  13.             sendto(socklisten,szbuf,sizeof(szbuf),0,(const struct sockaddr*)&addrclient,sizeof(addrclient));
  14.         }
  15.     }
复制代码
五、关闭套接字

        关闭我们上面创建的套接字,使用的是closesocket函数,传入的参数是套接字
  1. closesocket(socklisten);//关闭套接字
复制代码
六、卸载库

        使用WSACleanup函数即可,没有参数
  1. WSACleanup();//卸载库
复制代码
七、完整代码

  1. LIBS+=-lws2_32#include <QCoreApplication>#include <WinSock2.h>int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    //加载库
  2.     WORD wVersionRequested;
  3.     WSADATA wsaData;
  4.     int err;
  5.     /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
  6.     wVersionRequested = MAKEWORD(2, 2);
  7.     err = WSAStartup(wVersionRequested, &wsaData);
  8.     if (err != 0) {
  9.         /* Tell the user that we could not find a usable */
  10.         /* Winsock DLL.                                  */
  11.         printf("WSAStartup failed with error: %d\n", err);
  12.         return 1;
  13.     }
  14.     /* Confirm that the WinSock DLL supports 2.2.*/
  15.     /* Note that if the DLL supports versions greater    */
  16.     /* than 2.2 in addition to 2.2, it will still return */
  17.     /* 2.2 in wVersion since that is the version we      */
  18.     /* requested.                                        */
  19.     if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
  20.         /* Tell the user that we could not find a usable */
  21.         /* WinSock DLL.                                  */
  22.         printf("Could not find a usable version of Winsock.dll\n");
  23.         WSACleanup();
  24.         return 1;
  25.     }
  26.     else
  27.         printf("The Winsock 2.2 dll was found okay\n");    //创建套接字    SOCKET socklisten = socket(AF_INET,SOCK_DGRAM,0);
  28.     if(socklisten == INVALID_SOCKET){
  29.         printf("socket err\n");
  30.         WSACleanup();
  31.         return 1;
  32.     }
  33.     //绑定地址信息    sockaddr_in addrserver;    addrserver.sin_family = AF_INET;    addrserver.sin_addr.S_un.S_addr=0;    addrserver.sin_port = htons(8899);    if(SOCKET_ERROR == bind(socklisten,(const struct sockaddr*)&addrserver,sizeof(addrserver))){        printf("bind err\n");        closesocket(socklisten);        WSACleanup();        return 1;    }    //接收数据recvfrom
  34.     char szbuf[1024]={0};
  35.     sockaddr_in addrclient;
  36.     int nsize = sizeof(addrclient);
  37.     while(1)
  38.     {
  39.         int nreadnum = recvfrom(socklisten,szbuf,sizeof(szbuf),0,(struct sockaddr*)&addrclient,&nsize);
  40.         if(nreadnum >0)
  41.         {
  42.             printf("%s say: %s\n",inet_ntoa(addrclient.sin_addr),szbuf);
  43.             scanf_s("%s",szbuf);
  44.             //发送数据
  45.             sendto(socklisten,szbuf,sizeof(szbuf),0,(const struct sockaddr*)&addrclient,sizeof(addrclient));
  46.         }
  47.     }    closesocket(socklisten);//关闭套接字
  48.     WSACleanup();//卸载库    return a.exec();}
复制代码



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表