【Linux c】socket+thread【preIot project】

本文介绍了一种UE设备如何在TS节点与NB节点间进行数据包收发的具体实现方式,包括了多线程处理接收与发送过程中的数据包、数据校验等关键步骤。UE负责平衡两节点间的数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

requirement:    TS <----->UE<---->NB   TS and NB are two network nodes, they  communicate with UE.  UE make its all effort to balance the different communication with the TS and NB separately

ue.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <pthread.h>
#include <errno.h>

#define TS_IP "127.0.0.1"
#define NB_IP "109.105.2.136"
#define UE_PORT 7000
#define TS_PORT 5000
#define NB_PORT 6000
#define MAX 65536+16

struct argument{

	int fd;  
	int enable;
	pthread_mutex_t mut;
};	

int check_cmd(unsigned char data[MAX], int sum){
	
	int length;
	
	length = data[2] * 256 + data[3];
	
	if((sum - 4 == length) && !(data[0] == 0x03 && data[1] == 0x02))
		return 1;
	
	if((sum - 4 == length) && !(data[0] == 0x03 && data[1] == 0x03))
		return 1;
	
	if(sum - 16 == length)
		return 1;		
	
	return 0;
}

void receive_from_TSorNB_thread(void *arg_thread){
	
	int id;
	int i;
	int sock;
	struct sockaddr_in socket_addr;
	int socket_addr_len;
	unsigned char data[MAX] = {0}; 
	unsigned char data_TS[MAX] = {0};
	unsigned char data_NB[MAX] = {0};
	int length_TS = 0;
	int length_NB = 0;
	int sum_TS = 0;
	int sum_NB = 0; 
	int ret = 0;
	struct argument *arg;
	
	arg = ( struct argument * )arg_thread;

	bzero(&socket_addr,sizeof(socket_addr));
	socket_addr.sin_family = AF_INET;
	socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	socket_addr.sin_port = htons(UE_PORT);		
	socket_addr_len = sizeof(socket_addr);

	if((sock = socket(AF_INET,SOCK_DGRAM, 0)) < 0){
		
		perror("Socket");
		
		return ;
	}
	
	bind(sock, (struct sockaddr *)&socket_addr, sizeof(socket_addr));		
	
	while(1){

		ret = recvfrom(sock, data, sizeof(data), 0, (struct sockaddr *)&socket_addr, &socket_addr_len);

		//from TS 
		if(strcmp(inet_ntoa(socket_addr.sin_addr), TS_IP) == 0 ){
				
			for(i = 0; i < ret; i++){ 					
				
				data_TS[sum_TS+i] = data[i];
				
			}
			sum_TS = sum_TS + ret;

			if(check_cmd(data_TS, sum_TS) == 1){  		//full package
				
				if(data_TS[0] == 0x01 && data_TS[1] == 0x10){
					
					arg->enable = 1;
					
				}

				write(arg->fd, data_TS, sum_TS);

				sum_TS = 0;
				memset(data_TS, 0, sizeof(data_TS));			
			
			}
			
		}
		
		//from NB
		if(strcmp(inet_ntoa(socket_addr.sin_addr), NB_IP) == 9 ){

			for(i = 0; i < ret; i++){ 					//not full 
				
				data_NB[sum_NB+i] = data[i];
				
			}
			sum_NB = sum_NB + ret;
			
			if(check_cmd(data_NB, sum_NB) == 1){  		//full package

				write(arg->fd, data_NB, sum_NB);

				sum_NB = 0;
				memset(data_NB, 0, sizeof(data_NB));			
			
			}
			
		}
		
		memset(data, 0, ret);
		
		sleep(1);
	}
	
	return ;	
}
		
void send_to_TSorNB_thread(void *arg_thread){

	int id;
	int i;
	unsigned char data[MAX] = {0};
	unsigned char buffer[MAX] = {0};
	struct argument *arg;	
	int flag = 0;      
	int ret = 0;
	int sock = 0;
	int sum = 0;
	int length = 0;
	struct sockaddr_in socket_addr_TS;
	struct sockaddr_in socket_addr_NB;
	struct sockaddr_in addr_me;
	
    arg = ( struct argument * )arg_thread;
	
	//TS socket
	bzero(&socket_addr_TS, sizeof(socket_addr_TS));
	socket_addr_TS.sin_family = AF_INET;
	socket_addr_TS.sin_port = htons(TS_PORT);      
	socket_addr_TS.sin_addr.s_addr = inet_addr(TS_IP);  
	
	//NB socket
	bzero(&socket_addr_NB, sizeof(socket_addr_NB));
	socket_addr_NB.sin_family = AF_INET;
	socket_addr_NB.sin_port = htons(NB_PORT);      
	socket_addr_NB.sin_addr.s_addr = inet_addr(NB_IP);  
	
	//bind UE port
	bzero(&addr_me, sizeof(addr_me));
	addr_me.sin_family = AF_INET;
	addr_me.sin_port = htons(UE_PORT);      
	addr_me.sin_addr.s_addr = htonl(INADDR_ANY);

	if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){

		perror("socket");

		return ;
	}

	bind(sock, (struct sockaddr *)&addr_me, sizeof(addr_me));
		
	while(1){								

		while(1)
		{
			ret = read(arg->fd, data+sum, sizeof(data)-1-sum);
			
			sum = sum + ret;
						
			if(check_cmd(data, sum) == 1){
				
				break;
			}
			
		}

		if(data[0] == 0x01 && data[1] == 0x10){			//header 0x0110
		
			arg->enable = 0;
			
		}
		
		if(arg->enable == 1){

			if (data[0] == 0x03 && data[1] == 0x01 )
				sendto(sock, data, sum, 0, (struct sockaddr *)&socket_addr_TS, sizeof(socket_addr_TS));
			
			if (data[0] == 0x03 && data[1] == 0x03)
				sendto(sock, data, sum, 0, (struct sockaddr *)&socket_addr_NB, sizeof(socket_addr_NB));		
			
		}

		sum = 0;
		memset(data, 0, sizeof(data));
		
		sleep(1);
		
	}

	return ;
}

void main(void){

	int fd;
	struct argument arg;
	pthread_t thread[2];   

	fd = open("/dev/my_misc_dev", O_RDWR);
	
	if(fd != -1){

		arg.fd = fd;
		arg.enable = 0;
		
		pthread_create(&thread[0], NULL, (void *)(&receive_from_TSorNB_thread), (void*)&arg);	
		pthread_create(&thread[1], NULL, (void *)(&send_to_TSorNB_thread), (void*)&arg);
	
	}

	sleep(1000000);
	
	return ;
}
Makefile:

pcie:pc.c
	gcc -o pc pc.c -lpthread
clean:
	rm -fr *.o *~



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值