文章目录
- 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 $*
测试结果如下:
先启动客户端
再启动服务端
- 参考:networking - 使用 nc (netcat) 广播消息,Linux c udp广播,nc工具测试tcp/udp协议-爱代码爱编程