千家信息网

C++ Socket如何实现TCP与UDP网络编程

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章将为大家详细讲解有关C++ Socket如何实现TCP与UDP网络编程,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言socket编程分为TCP和UDP两
千家信息网最后更新 2026年11月02日C++ Socket如何实现TCP与UDP网络编程

这篇文章将为大家详细讲解有关C++ Socket如何实现TCP与UDP网络编程,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    前言

    socket编程分为TCP和UDP两个模块,其中TCP是可靠的、安全的,常用于发送文件等,而UDP是不可靠的、不安全的,常用作视频通话等。

    如下图:

    头文件与库:

    #include #pragma comment(lib, "ws2_32.lib")

    准备工作:

    创建工程后,首先右键工程,选择属性

    然后选择 C/C++ - 预处理器 - 预处理器定义

    将字符串 _WINSOCK_DEPRECATED_NO_WARNINGS 添加到里面去,点击应用即可!

    TCP

    连接过程图:

    创建tcp服务器和客户端都是按照上图的步骤来操作的!

    1). 服务器

    初始化套接字库
    对应图中socket()

    WORD wVersion;WSADATA wsaData;int err;// 设置版本,可以理解为1.1wVersion = MAKEWORD(1, 1);       // 例:MAKEWORD(a, b) --> b | a << 8 将a左移8位变成高位与b合并起来// 启动err = WSAStartup(wVersion, &wsaData);

    创建tcp套接字
    对应图中socket()

    // AF_INET:ipv4   AF_INET6:ipv6SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);

    绑定到本机
    对应图中bind()

    // 准备绑定信息SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);     // 设置绑定网卡addrSrv.sin_family = AF_INET;         // 设置绑定网络模式addrSrv.sin_port = htons(6000);               // 设置绑定端口// hton: host to network  x86:小端    网络传输:htons大端// 绑定到本机int retVal = bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

    监听
    对应图中listen()

    // 同时能接收10个链接,主要看参数二的设置个数listen(sockSrv, 10);

    接收连接请求,返回针对客户端的套接字
    对应图中accept()

    SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrCli, &len);

    发送数据
    对应图中write()

    sprintf_s(sendBuf, "hello client!\n");int iSend = send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);

    接收数据
    对应图中read()

    recv(sockConn, recvBuf, 100, 0);

    关闭套接字
    对应图中close()

    closesocket(sockConn);

    清理套接字库

    WSACleanup();

    具体实现代码:

    #include #include #include #pragma comment(lib, "ws2_32.lib")int main(void) {        // 1.初始化套接字库        WORD wVersion;        WSADATA wsaData;        int err;        // 设置版本,可以理解为1.1        wVersion = MAKEWORD(1, 1);       // 例:MAKEWORD(a, b) --> b | a << 8 将a左移8位变成高位与b合并起来        // 启动        err = WSAStartup(wVersion, &wsaData);        if (err != 0) {                return err;        }        // 检查:网络低位不等于1 || 网络高位不等于1        if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {                // 清理套接字库                WSACleanup();                return -1;        }        // 2.创建tcp套接字              // AF_INET:ipv4   AF_INET6:ipv6        SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);        // 准备绑定信息        SOCKADDR_IN addrSrv;        addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);     // 设置绑定网卡        addrSrv.sin_family = AF_INET;         // 设置绑定网络模式        addrSrv.sin_port = htons(6000);               // 设置绑定端口        // hton: host to network  x86:小端    网络传输:htons大端        // 3.绑定到本机        int retVal = bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));        if (retVal == SOCKET_ERROR) {                printf("Failed bind:%d\n", WSAGetLastError());                return -1;        }        // 4.监听,同时能接收10个链接        if (listen(sockSrv, 10) == SOCKET_ERROR) {                printf("Listen failed:%d", WSAGetLastError());                return -1;        }        std::cout << "Server start at port: 6000" << std::endl;        SOCKADDR_IN addrCli;        int len = sizeof(SOCKADDR);        char recvBuf[100];        char sendBuf[100];        while (1) {                // 5.接收连接请求,返回针对客户端的套接字                SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrCli, &len);                if (sockConn == SOCKET_ERROR) {                        //printf("Accept failed:%d", WSAGetLastError());                        std::cout << "Accept failed: " << WSAGetLastError() << std::endl;                        break;                }                //printf("Accept client IP:[%s]\n", inet_ntoa(addrCli.sin_addr));                std::cout << "Accept client IP: " << inet_ntoa(addrCli.sin_addr) << std::endl;                // 6.发送数据                sprintf_s(sendBuf, "hello client!\n");                int iSend = send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);                if (iSend == SOCKET_ERROR) {                        std::cout << "send failed!\n";                        break;                }                // 7.接收数据                recv(sockConn, recvBuf, 100, 0);                std::cout << recvBuf << std::endl;                // 关闭套接字                closesocket(sockConn);        }        // 8.关闭套接字        closesocket(sockSrv);        // 9.清理套接字库        WSACleanup();        return 0;}

    2). 客户端

    初始化套接字库
    对应图中socket()

    WORD wVersion;WSADATA wsaData;int err;// 可以理解为1.1wVersion = MAKEWORD(1, 1);       // 例:MAKEWORD(a, b) --> b | a << 8 将a左移8位变成高位与b合并起来// 启动err = WSAStartup(wVersion, &wsaData);// 创建TCP套接字SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);

    连接服务器
    对应图中connect()

    // 连接服务器int err_log = connect(sockCli, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

    发送数据到服务器
    对应图中write()

    char sendBuf[] = "你好,服务器,我是客户端!";send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);

    接收服务器的数据
    对应图中read()

    char recvBuf[100];recv(sockCli, recvBuf, sizeof(recvBuf), 0);

    关闭套接字并清除套接字库
    对应图中close()

    closesocket(sockCli);WSACleanup();

    具体实现代码:

    #include #include #pragma comment(lib, "ws2_32.lib")int main(void) {        // 1.初始化套接字库        WORD wVersion;        WSADATA wsaData;        int err;        // 可以理解为1.1        wVersion = MAKEWORD(1, 1);       // 例:MAKEWORD(a, b) --> b | a << 8 将a左移8位变成高位与b合并起来        // 启动        err = WSAStartup(wVersion, &wsaData);        if (err != 0) {                return err;        }        // 检查:网络地位不等于1 || 网络高位不等于1        if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {                // 清理套接字库                WSACleanup();                return -1;        }        // 创建TCP套接字        SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);        SOCKADDR_IN addrSrv;        addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");      // 服务器地址        addrSrv.sin_port = htons(6000);               // 端口号        addrSrv.sin_family = AF_INET;         // 地址类型(ipv4)        // 2.连接服务器        int err_log = connect(sockCli, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));        if (err_log == 0) {                printf("连接服务器成功!\n");                } else {                printf("连接服务器失败!\n");                return -1;        }        char recvBuf[100];        char sendBuf[] = "你好,服务器,我是客户端!";        // 3.发送数据到服务器        send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);        // 4.接收服务器的数据        recv(sockCli, recvBuf, sizeof(recvBuf), 0);        std::cout << recvBuf << std::endl;        // 5.关闭套接字并清除套接字库        closesocket(sockCli);        WSACleanup();        system("pause");        return 0;}

    运行效果:

    3). TCP聊天小项目

    下面是根据上面的代码修改的一个聊天小项目(使用到了多线程)

    只有一个服务器,服务器一直开启等待客户端连接;
    客户都安可以开启多个,且可以一直连续的与服务器进行发送接收消息;
    服务器给客户端发送数据,得通过1 - 9来区分到底给那个客户端发送消息,例如给第二个客户端发送消息:2你好,客户端
    客户端那边接收到的数据是:你好,客户端

    服务器代码:

    #include #include #include #include #include #include #include #include #include #pragma comment(lib, "ws2_32.lib")SOCKET sockSrv;std::vector vec_sockConn;std::vector vec_sockaddr_in;std::vector vec_sockIndex;// 这个结构体用作线程参数typedef struct SERVER_CLIENT {        SOCKET server;        SOCKADDR_IN client;        int clientIndex;}SC;// 判断有没有断开连接bool IsSocketClosed(SOCKET clientSocket) {        bool ret = false;        HANDLE closeEvent = WSACreateEvent();        WSAEventSelect(clientSocket, closeEvent, FD_CLOSE);        DWORD dwRet = WaitForSingleObject(closeEvent, 0);        if (dwRet == WSA_WAIT_EVENT_0)                ret = true;        else if (dwRet == WSA_WAIT_TIMEOUT)                ret = false;        WSACloseEvent(closeEvent);        return ret;}// 接收请求unsigned int WINAPI  ThreadAccept(LPVOID p) {        static int i = 0;        while (1) {                SOCKADDR_IN addrCli;                int len = sizeof(SOCKADDR);                // 5.接收连接请求,返回针对客户端的套接字                SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrCli, &len);                if (sockConn == SOCKET_ERROR) {                        printf("Accept failed:%d", WSAGetLastError());                }                // 存储当前服务器与客户端 连接绑定的socket                vec_sockIndex.emplace_back(i++);                vec_sockaddr_in.emplace_back(addrCli);                vec_sockConn.emplace_back(sockConn);                printf("\033[0;%d;40m客户端[%d]上线\033[0m\n", 31, i);        }                return 0;}unsigned int WINAPI  _ThreadRecv(LPVOID p) {        char recvBuf[100];        memset(recvBuf, 0, 100);        SC _sc = *(SC *)p;                while (1) {                Sleep(20);                if (IsSocketClosed(_sc.server) == true) {                        printf("客户端 [%d] 断开连接!\n", _sc.clientIndex + 1);                        break;                }                // 接收数据                recv(_sc.server, recvBuf, 100, 0);                if (strlen(recvBuf) == 0) {                        continue;                }                        printf("接收到客户端 [%d] 的消息:%s\n", _sc.clientIndex + 1, recvBuf);                memset(recvBuf, 0, 100);        }        return 0;}unsigned int WINAPI  ThreadRecv(LPVOID p) {        static int index = 0;        while (1) {                // 还没有客户端与服务器进行连接                if (vec_sockConn.size() == 0) {                        continue;                }                // 接收线程已经开启和客户端个数相等                if (vec_sockConn.size()  == index) {                        continue;                }                SC sc;                sc.server = vec_sockConn.at(index);                sc.client = vec_sockaddr_in.at(index);                sc.clientIndex = vec_sockIndex.at(index);                HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, _ThreadRecv, (void *)&sc, 0, NULL);                index++;                Sleep(20);        }        return 0;}int main(void) {        // 1.初始化套接字库        WORD wVersion;        WSADATA wsaData;        int err;        // 设置版本,可以理解为1.1        wVersion = MAKEWORD(1, 1);       // 例:MAKEWORD(a, b) --> b | a << 8 将a左移8位变成高位与b合并起来        // 启动        err = WSAStartup(wVersion, &wsaData);        if (err != 0) {                return err;        }        // 检查:网络低位不等于1 || 网络高位不等于1        if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {                // 清理套接字库                WSACleanup();                return -1;        }        // 2.创建tcp套接字              // AF_INET:ipv4   AF_INET6:ipv6        sockSrv = socket(AF_INET, SOCK_STREAM, 0);        // 准备绑定信息        SOCKADDR_IN addrSrv;        addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);     // 设置绑定网卡        addrSrv.sin_family = AF_INET;         // 设置绑定网络模式        addrSrv.sin_port = htons(6000);               // 设置绑定端口        // hton: host to network  x86:小端    网络传输:htons大端        // 3.绑定到本机        int retVal = bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));        if (retVal == SOCKET_ERROR) {                printf("Failed bind:%d\n", WSAGetLastError());                return -1;        }        // 4.监听,同时接收10个链接        if (listen(sockSrv, 10) == SOCKET_ERROR) {                printf("Listen failed:%d", WSAGetLastError());                return -1;        }        std::cout << "Server start at port: 6000" << std::endl;        // 线程句柄                            // 创建线程        HANDLE hThread_1 = (HANDLE)_beginthreadex(NULL, 0, ThreadAccept, NULL, 0, NULL);        HANDLE hThread_2 = (HANDLE)_beginthreadex(NULL, 0, ThreadRecv, NULL, 0, NULL);        //uiInit();        //editPrint(0, ">");        char sendBuf[100];        while (1) {                //printf("请输入发送内容:");                char c = getchar();                              // 输入发送给谁                scanf_s("%s", sendBuf, 100);        // 输入发送的内容                if (strlen(sendBuf) == 0) {                        printf("输入内容为空或者超长!\n");                }                // 1 至 9                if (c < '1' || c > '9' || vec_sockConn.size() == 0 || c - '0' >= vec_sockConn.size() + 1) {                        while ((c = getchar()) != '\n');       // 清空输入缓冲区                        memset(sendBuf, 0, 100);                        printf("输入内容不符合规则!\n");                        continue;                }                // 发送数据                int index = --c - '0'; // 因为下标是从零开始的,所以c要先自减                int iSend = send(vec_sockConn.at(index) , sendBuf, strlen(sendBuf) + 1, 0);                if (iSend == SOCKET_ERROR) {                        std::cout << "send failed!\n";                        break;                }                memset(sendBuf, 0, 100);                while ((c = getchar()) != '\n');       // 清空输入缓冲区        }        // 关闭套接字        std::vector::iterator it = vec_sockConn.begin();        for (; it != vec_sockConn.end(); it++) {                closesocket((SOCKET)(*it));        }        WaitForSingleObject(hThread_1, INFINITE);        WaitForSingleObject(hThread_2, INFINITE);        CloseHandle(hThread_1);        CloseHandle(hThread_2);        // 7.关闭套接字        closesocket(sockSrv);        // 8.清理套接字库        WSACleanup();        return 0;}

    客户端:

    #include #include #include #include #pragma comment(lib, "ws2_32.lib")SOCKET sockCli;// 判断有没有断开连接bool IsSocketClosed(SOCKET clientSocket) {        bool ret = false;        HANDLE closeEvent = WSACreateEvent();        WSAEventSelect(clientSocket, closeEvent, FD_CLOSE);        DWORD dwRet = WaitForSingleObject(closeEvent, 0);        if (dwRet == WSA_WAIT_EVENT_0)                ret = true;        else if (dwRet == WSA_WAIT_TIMEOUT)                ret = false;        WSACloseEvent(closeEvent);        return ret;}unsigned int WINAPI  ThreadRecv(LPVOID p) {        char recvBuf[100];        memset(recvBuf, 0, 100);        while (1) {                Sleep(20);                if (IsSocketClosed(sockCli) == true) {                        printf("服务器 断开连接!\n");                        break;                }                // 接收服务器的数据                recv(sockCli, recvBuf, sizeof(recvBuf), 0);                if (strlen(recvBuf) == 0) continue;                std::cout << recvBuf << std::endl;                memset(recvBuf, 0, 100);        }        return 0;}int main(void) {        // 1.初始化套接字库        WORD wVersion;        WSADATA wsaData;        int err;        // 可以理解为1.1        wVersion = MAKEWORD(1, 1);       // 例:MAKEWORD(a, b) --> b | a << 8 将a左移8位变成高位与b合并起来        // 启动        err = WSAStartup(wVersion, &wsaData);        if (err != 0) {                return err;        }        // 检查:网络地位不等于1 || 网络高位不等于1        if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {                // 清理套接字库                WSACleanup();                return -1;        }        // 创建TCP套接字        sockCli = socket(AF_INET, SOCK_STREAM, 0);        SOCKADDR_IN addrSrv;        addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");      // 服务器地址        addrSrv.sin_port = htons(6000);               // 端口号        addrSrv.sin_family = AF_INET;         // 地址类型(ipv4)        // 连接服务器        int err_log = connect(sockCli, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));        if (err_log == 0) {                printf("连接服务器成功!\n");        } else {                printf("连接服务器失败!\n");                return -1;        }        // 线程句柄                            // 创建线程        HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadRecv, NULL, 0, NULL);        char sendBuf[100];        while (1) {                //printf("请输入发送内容:");                scanf_s("%s", sendBuf, 100);                // 发送数据到服务器                send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);                memset(sendBuf, 0, 100);                char c;                while ((c = getchar()) != '\n');        }        WaitForSingleObject(hThread, INFINITE);        CloseHandle(hThread);        // 关闭套接字并清除套接字库        closesocket(sockCli);        WSACleanup();        system("pause");        return 0;}

    运行效果:

    UDP

    UDP就比较简单了,步骤比tcp要少一些。

    连接过程图:

    1). 服务器

    初始化套接字库

    WORD wVersion;WSADATA wsaData;int err;wVersion = MAKEWORD(1, 1);

    创建套接字

    SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);

    绑定

    // SOCKADDR_IN addrSrv; 省略了定义和赋值bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

    接收数据

    char recvBuf[100];recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);

    发送数据

    char sendBuf[] = "hello Client,I'm Server!\n";sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrCli, len);

    关闭

    closesocket(sockSrv);WSACleanup();

    具体实现代码:

    #include #include #pragma comment(lib, "ws2_32.lib")int main(void) {        // 初始化套接字库        WORD wVersion;        WSADATA wsaData;        int err;        wVersion = MAKEWORD(1, 1);        err = WSAStartup(wVersion, &wsaData);        if (err != 0) {                return err;        }        if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {                WSACleanup();                return -1;        }        // 创建套接字        SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);        SOCKADDR_IN addrSrv;        addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);        addrSrv.sin_family = AF_INET;        addrSrv.sin_port = htons(6001);        // 绑定到本机6001端口        bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));        // 接收请求,处理请求        SOCKADDR_IN addrCli;        int len = sizeof(SOCKADDR);        char sendBuf[] = "hello Client,I'm Server!\n";        char recvBuf[100];        std::cout << "start UDP server with port 6001" << std::endl;        while (1) {                // 接收数据                recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);                std::cout << "Recv:" << recvBuf << std::endl;                // 发送数据                sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrCli, len);                std::cout << "Send:" << sendBuf << std::endl;        }        closesocket(sockSrv);        WSACleanup();        return 0;}

    2). 客户端

    初始化套接字库

    WORD wVersion;WSADATA wsaData;int err;wVersion = MAKEWORD(1, 1);

    创建UDP套接字

    SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);SOCKADDR_IN addrSrv;

    接收数据

    char recvBuf[100];recvfrom(sockCli, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);

    发送数据

    char sendBuf[] = "hello Client,I'm Server!\n";sendto(sockCli, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrSrv, len);

    关闭

    closesocket(sockSrv);WSACleanup();

    具体实现代码:

    #include #include #pragma comment(lib, "ws2_32.lib")int main(void) {        // 初始化套接字库        WORD wVersion;        WSADATA wsaData;        int err;        wVersion = MAKEWORD(1, 1);        err = WSAStartup(wVersion, &wsaData);        if (err != 0) {                return err;        }        if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {                WSACleanup();                return -1;        }        // 创建UDP套接字        SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);        SOCKADDR_IN addrSrv;        addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");        addrSrv.sin_family = AF_INET;        addrSrv.sin_port = htons(6001);        SOCKADDR_IN addrCli;        int len = sizeof(SOCKADDR);        char sendBuf[] = "hello, I'm Client!\n";        char recvBuf[100];        std::cout << "send to Server: " << sendBuf << std::endl;        sendto(sockCli, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrSrv, len);        recvfrom(sockCli, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);        std::cout << "recv from: " << recvBuf << std::endl;        closesocket(sockCli);        WSACleanup();        system("pause");        return 0;}

    运行效果:

    关于"C++ Socket如何实现TCP与UDP网络编程"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

    服务器 服务 客户 套接字 数据 字库 客户端 网络 图中 高位 输入 代码 内容 线程 本机 你好 地址 消息 端口 准备 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 国智互联网科技 互联网科技媒体 米客互联网科技 滨湖区互联网智能科技产品供应 成都互联网科技公司100强 宜昌元轩互联网科技有限公司 米聚互联网科技南京有限公司排面 广州新华互联网科技学校电竞方面 华夏恒生科技与互联网科技 深圳艾果互联网通讯科技 用友工业互联网科技发展 卓翼科技产业互联网合作 北京市互联网新科技 产业互联网科技服务公司 上海同邻互联网科技有限公司规模 福建互联网展示科技馆设计 全球科技与互联网公司市值变化 张家口科技产业互联网平台 青岛易易互联网科技 互联网科技企业文化 互联网科技海报 智能科技公司是互联网公司吗 丰台科技园 互联网公司 汉立互联网科技有限公司联系电话 阿里互联网科技公司 互联网科技创新服务 语蝶互联网科技有限公司 消费医药和互联网科技 科技互联网公司两年变化 互联网科技自媒体灵感
    0