刘俊凯 发表于 2024-11-27 22:43:05

UDP服务器简朴素现(C)

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

        要用到Winsock2库里的WSAStartup函数,须要包罗相应的头文件。函数的返回值是一个整型,通过检察VS官方资助文档,我们判定加载库是否乐成。代码如下:
//加载库
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
      /* Tell the user that we could not find a usable */
      /* Winsock DLL.                                  */
      printf("WSAStartup failed with error: %d\n", err);
      return 1;
    }

    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
      /* Tell the user that we could not find a usable */
      /* WinSock DLL.                                  */
      printf("Could not find a usable version of Winsock.dll\n");
      WSACleanup();
      return 1;
    }
    else
      printf("The Winsock 2.2 dll was found okay\n"); 二、创建套接字

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

        绑定IP地址使用的函数是bind函数。函数的返回值是一个整型,根据函数的返回值来判定IP绑定是否乐成,失败返回SOCKET_ERROR,此时不但要卸载库,还要关闭套接字。
        为了方便设置端标语和IP,我们使用sockaddr_in,传入函数时,再逼迫范例转换将其地址转换为sockaddr*范例。
//绑定地址信息
    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函数。函数含6个参数,分别是:界说的套接字;输出参数,字符串范例,用来存放收到的消息;字符串长度;标志位(填0即可);输出参数,是sockaddr范例的布局体指针,表现消息的泉源;消息泉源布局体的长度的地址。
若能正常吸收,则返回值>0;假如连接关闭,则返回0,假如吸收非常返回错误信息。
在能正常收到消息的情况下,我们打印对端IP地址 和 用来存放消息的字符串即消息内容。这里我们使用 inet_ntoa函数将ulong型IP表现转换为十进制字符串四等分型IP表现。
           发送消息使用sendto函数,函数含6个参数,分别是:上述套接字;字符串,用来存放发送内容;字符串的长度;标志位,填0即可;客户端的地址;客户端的大小
//接收数据recvfrom
    char szbuf={0};
    sockaddr_in addrclient;
    int nsize = sizeof(addrclient);
    while(1)
    {
      int nreadnum = recvfrom(socklisten,szbuf,sizeof(szbuf),0,(struct sockaddr*)&addrclient,&nsize);
      if(nreadnum >0)
      {
            printf("%s say: %s\n",inet_ntoa(addrclient.sin_addr),szbuf);
            scanf_s("%s",szbuf);
            //发送数据
            sendto(socklisten,szbuf,sizeof(szbuf),0,(const struct sockaddr*)&addrclient,sizeof(addrclient));

      }
    } 五、关闭套接字

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

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

LIBS+=-lws2_32#include <QCoreApplication>#include <WinSock2.h>int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    //加载库
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
      /* Tell the user that we could not find a usable */
      /* Winsock DLL.                                  */
      printf("WSAStartup failed with error: %d\n", err);
      return 1;
    }

    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
      /* Tell the user that we could not find a usable */
      /* WinSock DLL.                                  */
      printf("Could not find a usable version of Winsock.dll\n");
      WSACleanup();
      return 1;
    }
    else
      printf("The Winsock 2.2 dll was found okay\n");    //创建套接字    SOCKET socklisten = socket(AF_INET,SOCK_DGRAM,0);
    if(socklisten == INVALID_SOCKET){
      printf("socket err\n");
      WSACleanup();
      return 1;
    }
    //绑定地址信息    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
    char szbuf={0};
    sockaddr_in addrclient;
    int nsize = sizeof(addrclient);
    while(1)
    {
      int nreadnum = recvfrom(socklisten,szbuf,sizeof(szbuf),0,(struct sockaddr*)&addrclient,&nsize);
      if(nreadnum >0)
      {
            printf("%s say: %s\n",inet_ntoa(addrclient.sin_addr),szbuf);
            scanf_s("%s",szbuf);
            //发送数据
            sendto(socklisten,szbuf,sizeof(szbuf),0,(const struct sockaddr*)&addrclient,sizeof(addrclient));

      }
    }    closesocket(socklisten);//关闭套接字
    WSACleanup();//卸载库    return a.exec();}


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: UDP服务器简朴素现(C)