Windows平台实现UDP通信

9 篇文章 0 订阅
这篇博客介绍了如何在Windows环境下,利用Visual Studio 2019进行UDP(用户数据报协议)的客户端和服务器端编程。作者通过创建两个C++项目,分别展示了UDP服务器端和客户端的代码实现,用于接收和发送数据。代码中包含了Winsock2的初始化、套接字创建、绑定端口、数据接收与发送等关键步骤。
摘要由CSDN通过智能技术生成

有两个学弟找我问windows上开发udp的相关问题,自己在vs 2019上面建立两个项目试一下。具体代码如下:

接收端写法

接收数据端,使用while循环等待数据到来并解析,单线程。暂且命名为UDP_Server.cpp


#include<stdio.h>
#include<tchar.h>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <WS2tcpip.h>
using namespace std;


#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])//_tmain,要加#include <tchar.h>才能用
{
    WSAData wsd;           //初始化信息
    SOCKET soRecv;         //接收SOCKET
    char* pszRecv = NULL;  //接收数据的数据缓冲区指针
    int nRet = 0;
    //int i = 0;
    int dwSendSize = 0;
    SOCKADDR_IN siRemote, siLocal;    //远程发送机地址和本机接收机地址

    //启动Winsock
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {
        cout << "WSAStartup Error = " << WSAGetLastError() << endl;
        return 0;
    }
    else {
        cout << "start Success" << endl;
    }

    //创建socket
    soRecv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (soRecv == SOCKET_ERROR) {
        cout << "socket Error = " << WSAGetLastError() << endl;
        return 1;
    }
    else {
        cout << "socket Success" << endl;
    }

    //设置端口号
    int nPort = 5150;

    siLocal.sin_family = AF_INET;
    siLocal.sin_port = htons(nPort);
    //siLocal.sin_addr.s_addr = inet_addr("127.0.0.1");
    inet_pton(AF_INET, "127.0.0.1", (void*)&siLocal.sin_addr.s_addr);

    //绑定本地地址到socket
    if (bind(soRecv, (SOCKADDR*)&siLocal, sizeof(siLocal)) == SOCKET_ERROR) {
        cout << "bind Error = " << WSAGetLastError() << endl;
        return 1;
    }
    else {
        cout << "bind Success" << endl;
    }

    //申请内存
    pszRecv = new char[4096];
    if (pszRecv == NULL) {
        cout << "pszRecv new char Error " << endl;
        return 0;
    }
    else {
        cout << "pszRecv new char Success" << endl;
    }

    // 一直等待数据
    while(true){
    //for (int i = 0; i < 30; i++) {
        dwSendSize = sizeof(siRemote);
        cout << "开始等待数据..." << endl;
        //开始接受数据
        nRet = recvfrom(soRecv, pszRecv, 4096, 0, (SOCKADDR*)&siRemote, &dwSendSize);
        cout << "收到数据!!" << endl;
        if (nRet == SOCKET_ERROR) {
            cout << "recvfrom Error " << WSAGetLastError() << endl;
            break;
        }
        else if (nRet == 0) {
            break;
        }
        else {
            pszRecv[nRet] = '\0';
            char sendBuf[20] = { '\0' };
            inet_ntop(AF_INET, (void*)&siRemote.sin_addr, sendBuf, 16);
            cout << "IP地址: " << sendBuf << endl
                << "数据: " << pszRecv << endl;
        }
    }
    //关闭socket连接
    closesocket(soRecv);
    delete[] pszRecv;

    //清理
    WSACleanup();
    system("pause");
    return 0;
}

发送端写法

发送数据端,每次发送30个字符串,命名为UDP_Client.cpp

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <WS2tcpip.h>
using namespace std;

#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
    cout << "hello world" << endl;
    WSAData wsd;           //初始化信息
    SOCKET soSend;         //发送到的目的SOCKET
    int nRet = 0;
    int dwSendSize = 0;
    SOCKADDR_IN siLocal;    //本机接收机地址

    //启动Winsock
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {/*进行WinSocket的初始化,
        windows 初始化socket网络库,申请2,2的版本,windows socket编程必须先初始化。*/
        cout << "WSAStartup Error = " << WSAGetLastError() << endl;
        return 0;
    }
    else {
        cout << "WSAStartup Success" << endl;
    }

    //创建socket

    //AF_INET 协议族:决定了要用ipv4地址(32位的)与端口号(16位的)的组合
    //SOCK_DGRAM --  UDP类型,不保证数据接收的顺序,非可靠连接;
    soSend = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (soSend == SOCKET_ERROR) {
        cout << "socket Error = " << WSAGetLastError() << endl;
        return 1;
    }
    else {
        cout << "socket Success" << endl;
    }

    //设置端口号
    int nPort = 5150;
    siLocal.sin_family = AF_INET;
    siLocal.sin_port = htons(nPort);
    //siLocal.sin_addr.s_addr = inet_addr("127.0.0.1");
    inet_pton(AF_INET, "127.0.0.1", (void*)&siLocal.sin_addr.s_addr);


    for (int i = 0; i < 30; i++) {
        //开始发送数据
        //发送数据到指定的IP地址和端口
        nRet = sendto(soSend, "123 mutouren", strlen("123 mutouren"), 0, (SOCKADDR*)&siLocal, sizeof(SOCKADDR));
        if (nRet == SOCKET_ERROR) {
            cout << "sendto Error " << WSAGetLastError() << endl;
            break;
        }
        else {
            cout << "sendto Success" << endl;
        }
    }
    //关闭socket连接
    closesocket(soSend);
    //清理
    WSACleanup();

    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Antrn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值