https://blog.csdn.net/guxch/article/details/7041052
https://blog.csdn.net/sinat_20184565/article/details/79567057
https://blog.csdn.net/ace_fei/article/details/6412069
udp广播示例
unix套接字可靠传输
只能客户端到服务端,服务端无法sendto
接收端
recvfrom介绍
https://blog.csdn.net/mm7758521/article/details/1750170?locationNum=7&fps=1
本地进程间通讯方式的一种,unix可靠传输
接收端
rec.c
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#define LOCAL_KEYEVENT_PATH "/tmp/key_event.socket"
void receivekeyevent(int eventdata)
{
int fd;
struct sockaddr_un un;
int ret;
int key;
int addr_len;
int on = 1;
char buf[512] = {0};
int len;
if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
perror("socket error");
return ;
}
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strncpy(un.sun_path, LOCAL_KEYEVENT_PATH, sizeof(LOCAL_KEYEVENT_PATH));
//addr_len = sizeof(un.sun_family) + strlen(un.sun_path);
addr_len = sizeof(un);
printf("addr len is %d\n", addr_len);
printf("fd is %d\n", fd);
#if 0
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) != 0) {
perror("set socket error");
return;
}
#endif
//need to remove for can not bind
sprintf(buf, "rm %s -rf", LOCAL_KEYEVENT_PATH);
system(buf);
printf("%s\n", buf);
printf("bind here~~~\n");
ret = bind(fd, (struct sockaddr *)&un, addr_len);
if(ret < 0) {
perror("bind error");
exit(-1);
}
//must need here,other wize will cause receive error
len = sizeof(un);
while(1) {
ret = recvfrom(fd, &key, sizeof(key), 0, (struct sockaddr*)&un, &len);
if(ret < 0) {
printf("ret %d len:%d\n", ret, len);
perror("receive error");
break;
}
printf("ret:%d key:%d len:%d\n", ret, key, len);
}
close(fd);
printf("exit here\n");
}
int main(void)
{
int fd;
printf("send here~~~\n");
while(1) {
receivekeyevent(3);
printf("slleep 5\n");
sleep(5);
}
return 0;
}
发送端
send.c
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#define LOCAL_KEYEVENT_PATH "/tmp/key_event.socket"
void sendkeyevent(int eventdata)
{
int fd = -1;
struct sockaddr_un un;
int addr_len = -1;
int ret;
if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
perror("socket error");
return ;
}
printf("fd is %d\n", fd);
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strncpy(un.sun_path, LOCAL_KEYEVENT_PATH, sizeof(LOCAL_KEYEVENT_PATH));
//addr_len = sizeof(un.sun_family) + strlen(un.sun_path);
addr_len = sizeof(struct sockaddr_un);
printf("len;%d\n", addr_len);
if ((ret = sendto(fd, &eventdata, sizeof(int), 0, (struct sockaddr *)&un, addr_len)) < 0) {
perror("sendkeyevent failed");
}else{
printf("sendkeyevent ok ret:%d\n", ret);
}
close(fd);
}
int main(void)
{
int fd;
int count = 0;
printf("send here~~~\n");
while(1) {
sendkeyevent(count++);
sleep(1);
}
return 0;
}
udp广播交互
客户端发现设备
//UDP 发送广播信息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define HEADER_FINDER "{\"tp\":1001}"
void *localprint_udp_handle(void *arg)
{
struct sockaddr_in from;
int sockfd = -1;
int ret;
int len;
int recvlen;
char rec_buf[1024];
struct sockaddr_in addr_cli;
//int opt = 0;
int port = *(int*)arg;
bzero(&from, sizeof(struct sockaddr_in));
from.sin_family = AF_INET;
from.sin_addr.s_addr = htonl(INADDR_ANY);
//from.sin_addr.s_addr = htonl(INADDR_BROADCAST);
from.sin_port = htons(port);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{
printf("[UDP]:Error(socket error)\n");
return NULL;
}
#if 0
ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&opt, sizeof(opt));
if(ret == -1)
{
printf("[UDP]:Error(set socket error)\n");
return NULL;
}
#endif
ret = bind(sockfd,(struct sockaddr *)&(from), sizeof(struct sockaddr_in));
if(ret == -1)
{
printf("bind error:%s<%s>, %d, \n", strerror(errno), __FUNCTION__, __LINE__);
return NULL;
}
while(1) {
len = sizeof(struct sockaddr);
memset(rec_buf, 0, sizeof(rec_buf));
memset(&addr_cli, 0, sizeof(struct sockaddr_in));
recvlen = recvfrom(sockfd, rec_buf, sizeof(rec_buf), 0, (struct sockaddr*)&addr_cli, &len);
if(recvlen <= 0) {
printf("read error....\n");
} else {
printf("recieve:0x%x, 0x%x, %d, <%s>\n", rec_buf[0], rec_buf[1], *((int*)&rec_buf[2]), &rec_buf[6]);
}
}
}
int main(int argc, char *argv[])
{
char brocastaddr[50] = {0};
int port;
int ret;
pthread_t pthread_udp;
if(argc == 2) {
//INADDR_BROADCAST
strcpy(brocastaddr, "255.255.255.255");
//strcpy(brocastaddr, "192.168.7.255");
//接收端口号并转换为int
port = atoi(argv[1]);
} else if(argc == 3) {
strcpy(brocastaddr, argv[1]);
port = atoi(argv[2]);
} else {
printf("please input ip and port\n");
return -1;
}
ret = pthread_create(&pthread_udp, NULL, localprint_udp_handle, &port);
if( port<1025 || port>65535 )//0~1024一般给系统使用,一共可以分配到65535
{
printf("port should be 1025~65535");
return -1;
}
//1.创建UDP socket
int udp_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_socket_fd == -1)
{
printf("create socket failed ! error message :%s\n", strerror(errno));
return -1;
}
//2.开启发送广播数据功能
int on = 1; //开启
ret = setsockopt(udp_socket_fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
if(ret < 0)
{
perror("setsockopt fail\n");
return -1;
}
//3.设置当前网段的广播地址
struct sockaddr_in bro_addr = {0};
bro_addr.sin_family = AF_INET;
bro_addr.sin_port = htons(port);
bro_addr.sin_addr.s_addr = inet_addr(brocastaddr); //设置为广播地址
char rec_buf[1024] = {0};
char send_buf[1024] = {0xbc, 0x01};//消息缓冲区
int *size = (int*)&send_buf[2];
*size = strlen(HEADER_FINDER);
strcpy(&send_buf[6], HEADER_FINDER);
struct sockaddr_in addr_cli = {0};
socklen_t len;
//4 发送数据
while(1)
{
len = sendto(udp_socket_fd, send_buf, strlen(HEADER_FINDER) + 6 + 1, 0, (struct sockaddr *)&bro_addr, sizeof(bro_addr));
//printf("len:%d, receive here:%s, %d\n", len, inet_ntoa(bro_addr.sin_addr), ntohs(bro_addr.sin_port));
len = sizeof(struct sockaddr);
bzero(rec_buf, sizeof(rec_buf));
memset(&addr_cli, 0, sizeof(addr_cli));
//ret = recv(udp_socket_fd, rec_buf, sizeof(rec_buf), 0);
//ret = recvfrom(udp_socket_fd, rec_buf, sizeof(rec_buf), 0, (struct sockaddr *)&addr_cli,&len);
printf("len:%d\n", ret);
sleep(2);
}
//5.关闭网络通信
close(udp_socket_fd);
return 0;
}