文章目录

  • ​​1.使用nc命令模拟UDP单播​​
  • ​​2.Linux C程序模拟UDP广播​​

1.使用nc命令模拟UDP单播

操作如下:

服务端
root@virtual-machine:/home/wangji# nc -lup 5188
wangji

客户端
root@virtual-machine:~# nc -u 127.0.0.1 5188
wangji



协议
root@-virtual-machine:~# netstat -anp|grep -i 5188
udp 0 0 127.0.0.1:39585 127.0.0.1:5188 ESTABLISHED 3699/nc
udp 0 0 127.0.0.1:5188 127.0.0.1:39585 ESTABLISHED 3695/nc

2.Linux C程序模拟UDP广播

使用setsocket给udp报文提供广播能力

需要利用这个函数开发套接字的发广播权限,并且需要客户端地址绑定为广播地址
setsocket(sockfd,SOL_SOCKET,SO_BROADCAST,&flag,sizeof(flag));

服务端代码:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <net/if.h>

#define PORT 9999
#define CLIENT_PORT 8888
void sys_perr(const char* str)
{
perror(str);
exit(1);
}

#define SER_PORT 9999

int main()
{
int fd = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in ser_addr,cli_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(fd,(struct sockaddr*)&ser_addr,sizeof(ser_addr));

int opt = 1;
setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt)); // 给当前socket广播权限

cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(CLIENT_PORT);
inet_pton(AF_INET,"127.0.0.1",&cli_addr.sin_addr.s_addr);
int i = 0;
char buf[1024];
while (1)
{
sprintf(buf,"hello %d\n",i++);
printf("buf=%s\n",buf);
int len = sendto(fd,buf,strlen(buf)+1,0,(struct sockaddr*)&cli_addr,sizeof(cli_addr));
printf("%d\n",len);
sleep(1);
}

return 0;
}

客户端代码:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <net/if.h>

#define CLIENT_PORT 8888
void sys_perr(const char* str)
{
perror(str);
exit(1);
}

#define SER_PORT 9999

int main()
{
int fd = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in cli_addr;
cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(CLIENT_PORT);
inet_pton(AF_INET,"127.0.0.1",&cli_addr.sin_addr.s_addr);
bind(fd,(struct sockaddr*)&cli_addr,sizeof(cli_addr));
char buf[1024];
while (1)
{
int len = recvfrom(fd,buf,sizeof(buf),0,NULL,0);
printf("%d\n",len);
write(STDOUT_FILENO,buf,len);
}

Cmake文件

cmake_minimum_required(VERSION 3.22)

project(Broudcasd C)

set(C_FLAFS -g -Wall)
set(CMAKE_C_COMPILE "gcc")
string(REPLACE ";" "" CMAKE_C_COMPILE "${C_FLAFS}")

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}//build/bin)

add_executable(server server.c)
add_executable(client client.c)

Build.sh

#!/bin/bash
set -x

SOURCE_DIR=`pwd`
BUILD_DIR="${SOURCE_DIR}/build"


rm -rf ${BUILD_DIR}
mkdir -p ${BUILD_DIR} \
&& cd ${BUILD_DIR} \
&& cmake ${SOURCE_DIR} \
&& make $*

测试结果如下:

先启动客户端

LInux模拟UDP广播_udp

再启动服务端

LInux模拟UDP广播_#include_02