Windows C语言 UDP通信demo

Posted 一只小阿大:)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows C语言 UDP通信demo相关的知识,希望对你有一定的参考价值。

目录

编译环境

我的demo是通过此文章从C++更改成的C,编译环境使用的是Mingw,如下图所示

快速入门

  1. 拷贝代码
  2. 编译
  3. 互传消息

编译指令

  1. 客户端:gcc .\\udpclient.c -lwsock32 -o udpclient.exe
  2. 服务端:gcc .\\udpserver.c -lwsock32 -o udpserver.exe


运行两个可执行程序

客户端给目标地址(127.0.0.1(本机地址)),端口为4567发送数据数据nihao

本机服务端接收到客户端发送的数据,准备给客户端返回数据nihaoya

这时候已经代表了一次通讯的结束,代码中还有对bye的判断,其实是多余的,如下图所示,这时候服务端接收到了bye,退出了程序,但是客户端没退出,需要强制退出,所以我认为这个bye是多余的。

服务端code

udpserver.c

#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 1024

#define SERVER_FAMILY AF_INET
#define SERVER_PORT 4567
#define SERVER_ADDR INADDR_ANY

void config_server(SOCKADDR_IN *addr_server)

    addr_server->sin_family = SERVER_FAMILY;
    addr_server->sin_port = htons(SERVER_PORT);
    addr_server->sin_addr.S_un.S_addr = SERVER_ADDR;


int main()

    WSADATA WSAData;
    char receBuf[BUFFER_SIZE];
    char Response[BUFFER_SIZE];
    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
    
        printf("init error\\n");
        exit(1);
    
    SOCKET sockServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sockServer == INVALID_SOCKET)
    
        printf("Failed socket() \\n");
        return 0;
    
    SOCKADDR_IN addr_Server; // 服务器的地址等信息
    config_server(&addr_Server);

    if (bind(sockServer, (SOCKADDR *)&addr_Server, sizeof(addr_Server)) == SOCKET_ERROR)
     // 服务器与本地地址绑定
        printf("Failed socket() %d \\n", WSAGetLastError());
        return 0;
    

    SOCKADDR_IN addr_Clt;
    int fromlen = sizeof(addr_Clt);

    while (true)
    
        int last = recvfrom(sockServer, receBuf, sizeof(receBuf), 0, (SOCKADDR *)&addr_Clt, &fromlen);
        printf("last:%d\\n", last);
        if (last > 0)
                                 // 判断接收到的数据是否为空
            receBuf[last] = '\\0'; // 给字符数组加一个'\\0',表示结束了。不然输出有乱码
            if (strcmp(receBuf, "bye") == 0)
            
                printf("client disconnect...\\n");
                closesocket(sockServer);
                return 0;
            
            else
            
                printf("receive data(%s):%s\\n", inet_ntoa(addr_Clt.sin_addr), receBuf);
            
        
        printf("please input send data:");
        scanf("%s", Response);
        printf("Response:%s,len:%d\\n", Response, strlen(Response));
        int r_sento = sendto(sockServer, Response, strlen(Response), 0, (SOCKADDR *)&addr_Clt, sizeof(SOCKADDR));
        printf("return :%d\\n", r_sento);
    

    closesocket(sockServer);

    WSACleanup();
    return 0;

客户端code

udpclient.c

#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 1024 // 缓冲区大小

#define SERVER_FAMILY AF_INET
#define SERVER_PORT 4567
#define SERVER_ADDR "127.0.0.1"

static char s_receBuf[BUFFER_SIZE]; // 发送数据的缓冲区
static char s_sendBuf[BUFFER_SIZE]; // 接受数据的缓冲区

void config_server(SOCKADDR_IN *addr_server)

    addr_server->sin_family = SERVER_FAMILY;
    addr_server->sin_port = htons(SERVER_PORT);
    addr_server->sin_addr.S_un.S_addr = inet_addr(SERVER_ADDR);


int main()

    SOCKET sock_Client; // 客户端用于通信的Socket
    WSADATA WSAData;

    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
    
        printf("init error");
        return -1;
     // 初始化

    sock_Client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // 创建客户端用于通信的Socket

    SOCKADDR_IN addr_server; // 服务器的地址数据结构
    config_server(&addr_server);

    SOCKADDR_IN sock;
    int len = sizeof(sock);
    while (true)
    
        printf("please input send data:");
        scanf("%s", s_sendBuf);
        sendto(sock_Client, s_sendBuf, strlen(s_sendBuf), 0, (SOCKADDR *)&addr_server, sizeof(SOCKADDR));
        // int last = recv(sock_Client, s_receBuf, strlen(s_receBuf), 0); // (调用recv和recvfrom都可以)
        int last = recvfrom(sock_Client, s_receBuf, sizeof(s_receBuf), 0, (SOCKADDR *)&sock, &len);
        printf("last:%d,%s\\n", last, s_receBuf);
        if (last > 0)
        
            s_receBuf[last] = '\\0'; // 给字符数组加一个'\\0',表示结束了。不然输出有乱码
            if (strcmp(s_receBuf, "bye") == 0)
            
                printf("server disconnect\\n");
                break;
            
            else
            
                printf("receive data:%s\\n", s_receBuf);
            
        
    

    closesocket(sock_Client);
    WSACleanup();

    return 0;

参考文章以及遇到的问题

参考文章:
C语言实现Windows下获取IP和MAC地址
Windows网络编程之UDP通信

其中Windows网络编程之UDP通信文章中客户端以及服务端都有bug,会造成通信失败,或者程序崩溃的情况。
服务端bug如下图所示


客户端bug如下图所示

以上是关于Windows C语言 UDP通信demo的主要内容,如果未能解决你的问题,请参考以下文章

请教用C语言编的借助UDP协议实现的文件传输的程序

有没有windows下c语言实现udp协议的代码

谁能给个C语言socket 通信,用UDP协议的代码例子。。

HP-Socket:高性能 TCP/UDP/HTTP 通信框架 | 软件推介

udp 通信程序

轻量级通信引擎StriveEngine —— C/S通信demo —— 使用二进制协议 (附源码)