• UDP(socket)数据访问和封装情况C++代码


    
    1. 配置QT下的pro文件

    TEMPLATE = app
    CONFIG += console
    CONFIG -= app_bundle
    CONFIG -= qt
     
    LIBS += -lWs2_32   ##标示使用window下的Ws2_32.lib-l表示要链接后面的库
    #-lWs2_32link Ws2_32.lib
     
    SOURCES += main.cpp 
        udp.cpp
     
    HEADERS += 
        udp.h

     

    1. 编写udp.h文件

    #ifndef UDP_H

    #define UDP_H

     

    #ifdef MYLINUX

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <arpa/inet.h>

    #include <unistd.h>

    #define SOCKET int

    #else

    #include <winsock2.h>

    #endif

     

    class myudp

    {

    private:

        SOCKET st;//类的内部成员通常是不暴露在类外部的

    public:

        myudp();

        myudp(const myudp &it);

        ~myudp();

    int socket_bind(short int port);

    int socket_send(const char *IP, const char *buf, int len);

    int socket_recv(char *buf, int len, char *srcIP);

    };

     

    #endif // UDP_H

     

    3.编写udp.cpp

    #include <stdio.h>
    #include <string.h>
    #include "udp.h"
     
    int myudp::socket_send(const char *IP, const char *buf, int len)
    {
        //建立一个socket,第一个參数是指定socket要用那个协议,AF_INET代表要用TCP/IP协议
        //第二个參数SOCK_DGRAM意思是要用UDP协议
        //第三个參数一般默认填0
        st = socket(AF_INET, SOCK_DGRAM, 0);//定义一个socket
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));//初始化结构addr;
        addr.sin_family = AF_INET;//代表要使用一个TCP/IP的地址
        addr.sin_port = htons(8080);//host to net short
        addr.sin_addr.s_addr = inet_addr(IP);
        //unsigned long laddr = inet_addr("192.168.6.200");
        //unsigned char *p = &laddr;
        //printf("%u,%u,%u,%u
    ", *(p), *(p + 1),*(p + 2), *(p + 3));
     
        size_t rc = 0;
        //发送udp数据
        rc = sendto(st, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr));
        return rc;
    }
     
    int myudp::socket_recv(char *buf, int len, char *srcIP)
    {
            struct sockaddr_in sendaddr;
            memset(&sendaddr, 0, sizeof(sendaddr));
     
    #ifdef MYLINUX
            socklen_t addrlen;
    #else
            int addrlen;
    #endif
            addrlen = sizeof(sendaddr);
            memset(buf, 0, len);
            //接收udp数据
            size_t rc = recvfrom(st, buf, len, 0, (struct sockaddr *)&sendaddr, &addrlen);
            //inet_ntoa(sendaddr.sin_addr);//这个函数是不可重入函数
            if (srcIP)
                strcpy(srcIP, inet_ntoa(sendaddr.sin_addr));
        return rc;
    }
     
    myudp::myudp()
    {
    #ifndef MYLINUX
        //初始化socket
        DWORD ver;
        WSADATA wsaData;
        ver = MAKEWORD(1, 1);//在调用WSAStatrtup要告诉widnows,我用什么版本号的socket
        WSAStartup(ver, &wsaData);//windows要求,仅仅要用socket,第一步。必须调用这个函数
        //初始化socket完毕
        //建立一个socket,第一个參数是指定socket要用那个协议,AF_INET代表要用TCP/IP协议
        //第二个參数SOCK_DGRAM意思是要用UDP协议
        //第三个參数一般默认填0
        st = socket(AF_INET, SOCK_DGRAM, 0);//定义一个socket
    #endif
    }
     
    myudp::myudp(const myudp &it)
    {
    }
     
    myudp::~myudp()
    {
    #ifdef MYLINUX
        close(st);
    #else
        closesocket(st);//使用完socket要将其关闭
        WSACleanup();//释放win socket内部的相关资源
    #endif
    }
     
    int myudp::socket_bind(short port)
    {
        struct sockaddr_in addr;
        //初始化结构addr;
        memset(&addr, 0, sizeof(addr));
        //代表要使用一个TCP/IP的地址
        addr.sin_family = AF_INET;
        //host to net short
        addr.sin_port = htons(port);
        //做为接收方,不须要指定详细的IP地址,接收的主机是什么IP,我就在什么IP上收数据
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        int rc = 0;
        return bind(st, (struct sockaddr *)&addr, sizeof(addr));
    }

    4.main.c的实现代码

    #include <iostream>
    #include "udp.h"
     
    using namespace std;
     
    int main(int argc, char *args[])
    {
        if (argc > 1)
        {
            myudp udp;
            char buf[1024] = {0};
            while(1)
            {
                memset(buf, 0, sizeof(buf));
                gets(buf);
                udp.socket_send(args[1], buf, strlen(buf));
                if (strncmp(buf, "exit", 4) == 0)
                    break;
            }
        }
        else
        {
            myudp udp;
            char buf[1024] = {0};
            if (udp.socket_bind(8080) > -1)
            {
                char ip[100] = {0};
                while(1)
                {
                    memset(buf, 0, sizeof(buf));
                    memset(ip, 0, sizeof(ip));
                    udp.socket_recv(buf, sizeof(buf), ip);
                    if (strncmp(buf, "exit", 4) == 0)
                        break;
                    cout << buf << endl;
                    cout << ip << endl;
                }
            }
        }
     
        cout << "over" << endl;
        return 0;
    }

     

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    C++文件(夹)选择对话框
    BCB中选择文件对话框TOpenDialog过滤后缀名使用方法
    pjlib深入剖析和使用详解
    PJNATH介绍 -- 开源的用于NAT穿透的ICE, STUN和TURN
    STUN, TURN, ICE介绍
    一个boost底下的线程池
    在Windows下编译WebRTC
    FEC(Forward Error Correction)前向纠错 UDPRTP 中使用用于改善无线等网络丢包等问题--转
    FEC之我见四
    FEC之异或运算应用
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4831252.html
Copyright © 2020-2023  润新知