/**************************************************************************************************************************************
*
* 字节序:数据以字节流的方式进行传输,底层都是采用二进制,字节流的顺序是由架构决定的,现在假设使用X86架构,是采用小端存储
* 网络字节序:
* 本地字节序:
*
* 大端存储:低地址存储高字节 当数据超过1个字节的时候才需要区分大端还是小端 假设int型 0x12345678 0x12 | 0x34 | 0x56 | 0x78
* 小端存储:低地址存储低字节 当数据超过1个字节的时候才需要区分大端还是小端 假设int型 0x12345678 0x78 | 0x56 | 0x34 | 0x12
*
* 设备A采用X86架构,所以设备A采用小端存储 待发送的数据 :0x12345678
* 设备B采用ARM架构,所以设备B采用大端存储 待接收的数据 :?
*
* 为了统一发送数据的格式,所以互联网传输的数据统一采用大端方式,为了方便开发,linux系统提供了转换的接口:htonl、htons、ntohl、ntohs
*
* h :host 主机/本地
* to: 转换
* n :net 网络
* l :long 长整型
* s :short 短整型
*
* htons:把本地字节序的一个短整型转换为网络字节序
* htonl:把本地字节序的一个长整型转换为网络字节序
* ntohs:把网络字节序的一个短整型转换为本地字节序
* ntohl:把网络字节序的一个长整型转换为本地字节序
* ***********************************************************************************************************************************/
/**********************************************************************************
*
* file name: brostcast.c
* author : [email protected]
* date : 2024/06/03
* function : 程序可以加入到一个多播组中并等待服务器发送数据包,并且程序还需要具有发送功能,如果收到数据包则把消息内容输出到终端,
* note : None
* CopyRight (c) 2024-2024 [email protected] All Right Reseverd
*
* *******************************************************************************/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define __PORT_SERVER 9999
#define GROUP_ADDR_01 "226.66.66.66"
char senbuf[128] = "123456";
char buf[128] = {0};
char buffer[128] = {0};
/* *********************************************************************************
*
*
* @function name: getsmg
* @brief : 接受多播组的信息
* @param :
* @arg:线程函数的一个void *地址
* @retval :
* NULL
* @date : 2024/06/03
* @version :1.0
* @note : NULL
*
*
* *******************************************************************************/
void *getmsg(void *arg)
{
int socketfd = *(int *)arg;
// 接受别的机发送地址
struct sockaddr_in source_addr;
socklen_t addr_len = sizeof(source_addr);
char *source_ip = inet_ntoa(source_addr.sin_addr);
while (1)
{
sleep(2);
recvfrom(socketfd,buf, sizeof(buf), 0, (struct sockaddr *)&source_addr,&addr_len); // 默认会阻塞
char *source_ip = inet_ntoa(source_addr.sin_addr);
printf(" [%s %s] = %s\n",source_ip, buffer, buf);
bzero(buf, sizeof(buf));
}
return NULL;
}
/* *********************************************************************************
*
*
* @function name: getsmg
* @brief : 向多播组发送信息
* @param :
* @arg:线程函数的一个void *地址
* @retval :
* NULL
* @date : 2024/06/03
* @version :1.0
* @note : NULL
*
*
* *******************************************************************************/
void *sedmsg(void *arg)
{
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET; // 协议族,是固定的
dest_addr.sin_port = htons(__PORT_SERVER); // 服务器端口,必须转换为网络字节序
dest_addr.sin_addr.s_addr = inet_addr(GROUP_ADDR_01);
while (1)
{
sleep(2);
sendto(*(int *)arg, senbuf, strlen(senbuf), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
}
return NULL;
}
int main(int argc,char *argv[])
{
time_t timep;
struct tm *p;
time(&timep);
p = gmtime(&timep);
//将系统时间写入缓冲区
sprintf(buffer, "%d年%d月%d日 %d:%d:%d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, 8 + p->tm_hour, p->tm_min, p->tm_sec);
//1.创建UDP套接字
int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_socket == -1)
{
fprintf(stderr, "udp socket error,errno:%d,%s\n", errno, strerror(errno));
exit(1);
}
//2.需要先绑定服务器的端口和地址,本机
struct sockaddr_in host_addr;
host_addr.sin_family = AF_INET; //协议族,是固定的
host_addr.sin_port = htons(__PORT_SERVER); //目标端口,必须转换为网络字节序
host_addr.sin_addr.s_addr = htonl(INADDR_ANY); //目标地址 "192.168.64.xxx" 已经转换为网络字节序 INADDR_ANY
bind(udp_socket,(struct sockaddr *)&host_addr, sizeof(host_addr));
//多播地址
int iRet = -1;
setsockopt(udp_socket, SOL_SOCKET, SO_REUSEADDR, &iRet, sizeof(iRet));
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(GROUP_ADDR_01); /* 多播组的IP地址 */
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
pthread_t snd;
pthread_t get;
pthread_create(&snd,NULL,sedmsg,&udp_socket);
pthread_create(&get,NULL,getmsg,&udp_socket);
pthread_join(snd, NULL);
pthread_join(get, NULL);
pthread_exit(NULL);
}
标签:NULL,字节,int,程序,socket,服务器发送,include,数据包,addr
From: https://www.cnblogs.com/wwwwariana/p/18233725