UDP通信 (C语言实现)

直接看代码吧      v๑乛◡乛๑

udp_server.c

/*********************************************************************************************************
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名:  udp_server.c
** 创   建   人: ***
**
** 文件创建日期: ** 年 ** 月 ** 日
**
** 描        述: UDP 回射服务器程序
*********************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
/*********************************************************************************************************
  宏定义
*********************************************************************************************************/
#define __UDP_ECHO_TYPE_CLIENT          1                               /* 客户端模式                   */
#define __UDP_ECHO_TYPE_SERVER          2                               /* 服务器模式                   */
#define __UDP_ECHO_TYPE                 (__UDP_ECHO_TYPE_SERVER)        /* 当前模式选择                 */
#define __UDP_ECHO_IP_CLIENT            "10.4.0.95"                     /* 客户端 IP 地址               */
#define __UDP_ECHO_IP_SERVER            "10.4.0.96"                     /* 服务器 IP 地址               */
#define __UDP_ECHO_PORT_CLIENT          8000                            /* 客户端端口号                 */
#define __UDP_ECHO_PORT_SERVER          8001                            /* 服务器端口号                 */
#define __UDP_ECHO_BUFF_SIZE_CLIENT     257                             /* 客户端接收缓冲区大小         */
#define __UDP_ECHO_BUFF_SIZE_SERVER     257                             /* 服务器接收缓冲区大小         */
/*********************************************************************************************************
** 函数名称: __UdpEchoServer
** 功能描述: UDP 回射服务器程序
** 输 入  : NONE
** 输 出  : ERROR
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static int  __UdpEchoServer (void){
    int                 iRet      = -1;                                 /* 操作结果                     */
    int                 sockFd    = -1;                                 /* socket 描述符                */
    socklen_t           uiAddrLen = sizeof(struct sockaddr_in);         /* 地址结构大小                 */
    register ssize_t    sstRecv   = 0;                                  /* 接收到的数据长度             */
    char                cRecvBuff[__UDP_ECHO_BUFF_SIZE_SERVER] = {0};   /* 接收缓冲区                   */
    struct sockaddr_in  sockaddrinLocal;                                /* 本地地址                     */
    struct sockaddr_in  sockaddrinRemote;                               /* 远端地址                     */

    fprintf(stdout, "UDP echo server start.\n");

    sockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);                  /* 创建 socket                  */
    if (sockFd < 0) {                                                   /* 操作失败                     */
        printf("UDP echo server socket error.\n");
        return  (-1);                                                   /* 错误返回                     */
    }

    /*
     * 初始化本地地址结构
     */
    memset(&sockaddrinLocal, 0, sizeof(sockaddrinLocal));               /* 清空地址信息                 */

    sockaddrinLocal.sin_len         = sizeof(struct sockaddr_in);       /* 地址结构大小                 */
    sockaddrinLocal.sin_family      = AF_INET;                          /* 地址族                       */
    sockaddrinLocal.sin_addr.s_addr = INADDR_ANY;
    sockaddrinLocal.sin_port        = htons(__UDP_ECHO_PORT_SERVER);    /* 绑定服务器端口               */

    iRet = bind(sockFd, (struct sockaddr *)&sockaddrinLocal, sizeof(sockaddrinLocal));
                                                                        /* 绑定本地地址与端口           */
    if (iRet < 0) {                                                     /* 绑定操作失败                 */
        close(sockFd);                                                  /* 关闭已经创建的 socket        */
        fprintf(stderr, "UDP echo server bind error.\n");
        return  (-1);                                                   /* 错误返回                     */
    }

    for (;;)
    {
        memset(&cRecvBuff[0], 0, __UDP_ECHO_BUFF_SIZE_SERVER);          /* 清空接收缓冲区               */
        sstRecv = recvfrom(sockFd,(void *)&cRecvBuff[0], __UDP_ECHO_BUFF_SIZE_SERVER,
                           0, (struct sockaddr *)&sockaddrinRemote, &uiAddrLen);
                                                                        /* 从远端接收数据               */
        if (sstRecv <= 0) {                                             /* 接收数据失败                 */
            if ((errno != ETIMEDOUT) && (errno != EWOULDBLOCK)) {       /* 非超时与非阻塞               */
                 close(sockFd);                                         /* 关闭已经创建的 socket        */
                 fprintf(stderr, "UDP echo server recvfrom error.\n");
                 return  (-1);
            }

            continue;
        }

        sendto(sockFd, (const void *)&cRecvBuff[0], sstRecv, 0,
               (const struct sockaddr *)&sockaddrinRemote, uiAddrLen);
    }//for

}
int main(int argc, char* argv[]){
    __UdpEchoServer();
    return 0;
}
/*********************************************************************************************************
  END
*********************************************************************************************************/

udp_client.c

/*********************************************************************************************************
** 文   件   名: udp_client.c
**
** 创   建   人: ***
**
** 文件创建日期: ** 年 ** 月 ** 日
**
** 描        述: UDP 回射客户端程序
*********************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
/*********************************************************************************************************
  宏定义
*********************************************************************************************************/
#define __UDP_ECHO_TYPE_CLIENT          1                               /* 客户端模式                   */
#define __UDP_ECHO_TYPE_SERVER          2                               /* 服务器模式                   */
#define __UDP_ECHO_TYPE                 (__UDP_ECHO_TYPE_CLIENT)        /* 当前模式选择                 */
#define __UDP_ECHO_IP_CLIENT            "10.4.0.96"                     /* 客户端 IP 地址               */
#define __UDP_ECHO_IP_SERVER            "10.4.0.95"                     /* 服务器 IP 地址               */
#define __UDP_ECHO_PORT_CLIENT          8000                            /* 客户端端口号               */
#define __UDP_ECHO_PORT_SERVER          8001                            /* 服务器端口号               */
#define __UDP_ECHO_BUFF_SIZE_CLIENT     257                             /* 客户端接收缓冲区大小       */
#define __UDP_ECHO_BUFF_SIZE_SERVER     257                             /* 服务器接收缓冲区大小       */
/*********************************************************************************************************
** 函数名称: __UdpEchoClient
** 功能描述: UDP 回射客户端程序
** 输 入  : NONE
** 输 出  : ERROR
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static int  __UdpEchoClient (void)
{
    int                  sockFd     = -1;                               /* socket 描述符                */
    socklen_t            uiAddrLen  = sizeof(struct sockaddr_in);       /* 地址结构大小                 */
    register ssize_t     sstRecv    = 0;                                /* 接收到的数据长度             */
    register ssize_t     sstSend    = 0;                                /* 接收到的数据长度             */
    const char          *pcSendData = "SylixOS Hello!\n";               /* 需要发送的字符串             */
    char                 cRecvBuff[__UDP_ECHO_BUFF_SIZE_CLIENT] = {0};  /* 接收缓冲区                   */
    struct sockaddr_in   sockaddrinRemote;                              /* 远端地址                     */

    fprintf(stdout, "UDP echo client start.\n");


    sockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);                  /* 创建 socket                  */
    if (sockFd < 0) {
        fprintf(stderr, "UDP echo client socket error.\n");
        return  (-1);
    }

    /*
     * 初始化远端地址结构
     */
    memset(&sockaddrinRemote, 0, sizeof(sockaddrinRemote));
    if (!inet_aton(__UDP_ECHO_IP_SERVER, &sockaddrinRemote.sin_addr)) { /* 地址转换错误                 */
        close(sockFd);                                                  /* 关闭已经创建的 socket        */
        fprintf(stderr, "UDP echo client get addr error.\n");
        return  (-1);                                                   /* 错误返回                     */
    }

    sockaddrinRemote.sin_len    = sizeof(struct sockaddr_in);           /* 地址结构大小                 */
    sockaddrinRemote.sin_family = AF_INET;                              /* 地址族                       */
    sockaddrinRemote.sin_port   = htons(__UDP_ECHO_PORT_SERVER);        /* 绑定服务器端口               */

    for (;;) {
        fprintf(stdout, "Send Data: %s", pcSendData);
        sstRecv = strlen(pcSendData);                                   /* 获取发送字符串长度           */
        sstSend = sendto(sockFd, (const void *)pcSendData, sstRecv, 0,
                         (const struct sockaddr *)&sockaddrinRemote, uiAddrLen);
                                                                        /* 发送数据到指定的服务器端     */
        if (sstSend <= 0) {                                             /* 发送数据失败                 */
            if ((errno != ETIMEDOUT) && (errno != EWOULDBLOCK)) {       /* 非超时与非阻塞               */
                 close(sockFd);                                         /* 关闭已经创建的 socket        */
                 fprintf(stderr, "UDP echo client sendto error.\n");
                 return  (-1);                                          /* 错误返回                     */
            }

            continue;                                                   /* 超时或非阻塞后重新运行       */
        }

        memset(&cRecvBuff[0], 0, __UDP_ECHO_BUFF_SIZE_CLIENT);
        sstRecv = recvfrom(sockFd, (void *)&cRecvBuff[0], __UDP_ECHO_BUFF_SIZE_SERVER,
                           0, (struct sockaddr *)&sockaddrinRemote, &uiAddrLen);
                                                                        /* 从远端接收数据               */
        if (sstRecv <= 0) {                                             /* 接收数据失败                 */
            if ((errno != ETIMEDOUT) &&(errno != EWOULDBLOCK)) {        /* 非超时与非阻塞               */
                 close(sockFd);                                         /* 关闭已经创建的 socket        */
                 fprintf(stderr, "UDP echo client recvfrom error.\n");
                 return  (-1);                                          /* 错误返回                     */
            }

            continue;                                                   /* 超时或非阻塞后重新运行       */
        }

        fprintf(stdout, "Recv Data: ");
        cRecvBuff[sstRecv] = 0;
        fprintf(stdout, "%s\n", &cRecvBuff[0]);

        sleep(5);                                                       /* 休眠一段时间                 */
    }//for

    return  (0);
}

int main(int argc, char* argv[]){
    __UdpEchoClient();
    return 0;
}
/*********************************************************************************************************
  END
*********************************************************************************************************/

 

  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
UDP组播通信是一种基于UDP协议的多播通信方式,可以在局域网内实现一对多的数据传输。以下是使用C语言实现UDP组播通信的基本步骤: 1. 创建UDP套接字: 使用`socket()`函数创建一个UDP套接字,指定协议族为`AF_INET`,类型为`SOCK_DGRAM`。 2. 设置组播地址和端口: 使用`setsockopt()`函数设置多播组地址和端口,其中IP地址为组播地址,端口为组播监听的端口。 3. 绑定套接字: 使用`bind()`函数将套接字绑定到本地IP地址和指定的端口上。 4. 加入组播组: 使用`setsockopt()`函数设置套接字的`IP_ADD_MEMBERSHIP`选项,将套接字加入到指定的组播组中。 5. 接收组播数据: 使用`recvfrom()`函数从套接字接收组播数据。 6. 发送组播数据: 使用`sendto()`函数将数据发送到指定的组播地址和端口。 下面是一个简单的UDP组播通信的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #define GROUP_ADDR "239.0.0.1" // 组播地址 #define PORT 8888 // 组播端口 int main() { int sockfd; struct sockaddr_in addr; char buffer[1024]; // 创建UDP套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket creation failed"); exit(EXIT_FAILURE); } // 设置组播地址和端口 memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(GROUP_ADDR); addr.sin_port = htons(PORT); // 绑定套接字 if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 加入组播组 struct ip_mreq mreq; memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = inet_addr(GROUP_ADDR); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { perror("setsockopt failed"); exit(EXIT_FAILURE); } // 接收组播数据 while (1) { memset(buffer, 0, sizeof(buffer)); if (recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL) < 0) { perror("recvfrom failed"); exit(EXIT_FAILURE); } printf("Received data: %s\n", buffer); } // 关闭套接字 close(sockfd); return 0; } ``` 这是一个组播接收端的示例代码,可以接收从同一组播地址和端口发送的数据。你可以根据需要修改代码来实现组播发送端。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值