udp可靠传输的一种

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广播示例

https://blog.csdn.net/nanfeibuyi/article/details/88540233?biz_id=102&utm_term=Linux-C%20%C2%A0UDP%E7%AE%80%E5%8D%95%E4%BE%8B%E5%AD%90&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~sobaiduweb~default-0-88540233&spm=1018.2118.3001.4187

https://blog.csdn.net/dxpqxb/article/details/38403199?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160326149319195188364357%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160326149319195188364357&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-2-38403199.first_rank_ecpm_v3_pc_rank_v2&utm_term=linux%E7%9A%84udp%E5%B9%BF%E6%92%AD%E4%BE%8B%E5%AD%90&spm=1018.2118.3001.4187

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;
	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值