简单的多线程数据传输
来源:互联网 发布:淘宝充值未到账怎么办 编辑:程序博客网 时间:2024/05/16 12:06
说明
为创建一份小型的工程代码,自己想出一个简单的数据传输任务。
主进程创建四个线程,st1,st2,st3,rt,让前三个线程向最后一个线程灌包,最后一个线程接收数据包。
目的IP: 10.21.100.152
目的端口:9001
各个进程被创建后立即进行相应的工作,灌包或者收包。rt接收到数据包后打印出相应的信息。
makefile
工程文件的编译会接触到makefile,下面是总结的常用的makfile变量
另外一些可能用到的:
STRIP: 去空格函数,去除开头和结尾出现的空字符
addprefix: 加前缀函数
$(addprefix <prefix>, <name-1>, <name-2>...<name-n>)该函数将前缀 <prefix> 加到各个 <name> 的前面去。
代码结构
图中的.a文件和.d文件是编译后产生的。
.a文件是静态库文件,.d文件为源文件的依赖关系的完整规则。
code
common.h
#ifndef COMMON_H#define COMMON_H#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <sched.h>#include <unistd.h>#include <sys/types.h>#include <malloc.h>#include <signal.h>#define Len 20#define Num 10#define TASK_JOIN 1typedef unsigned char UINT8;typedef unsigned short UINT16;typedef int INT32;typedef struct msg{ UINT8 context[Num][Len];}Msg;pthread_t g_st1;pthread_t g_st2;pthread_t g_st3;pthread_t g_rt;int g_rt_recv_sock;struct sockaddr_in g_sendto;struct sockaddr_in g_recvfr;pthread_t create_pthread(INT32 prior, INT32 policy, INT32 state, void *fn, void *args_p);void *msg_malloc(UINT8 dex);void handler(int arg);int recv_sock_set(UINT16 PORT);struct sockaddr_in send_sock_set(char *IP, UINT16 PORT);#endif
common.c
#include "../inc/common.h"pthread_t create_pthread(INT32 prior, INT32 policy, INT32 state, void *fn, void *args_p){ pthread_attr_t attr; struct sched_param param; pthread_t taskid; INT32 ret; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, policy); /* 调度策略 */ param.sched_priority = prior; /* 设定优先级 */ pthread_attr_setschedparam(&attr, ¶m); /* PTHREAD_SCOPE_SYSTEM: kernel level thread, PTHREAD_SCOPE_PROCESS: user level thread */ /* 设置线程优先级的有效范围,PTHREAD_SCOPE_SYSTEM表示和系统中所有线程竞争 */ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); /* PTHREAD_CREATE_DETACHED : detachstate thread 相分离线程 PTHREAD_CREATE_JOINABLE : joinable thread 可会合线程 */ if (state != 1) { pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); } /* PTHREAD_INHERIT_SCHED: inherit father thread's attr * PTHREAD_EXPLICIT_SCHED: use pthread_create() attr */ pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); if ((ret = pthread_create(&taskid, &attr, fn, args_p)) != 0) { printf("fail to create pthread: ret=%d\n", ret); /* 取得用户的识别码,等于0则是root */ if(getuid() != 0){ printf("Please run app with root user\n"); } return -1; } else{ pthread_attr_destroy(&attr); return taskid; }}void *msg_malloc(UINT8 dex){ void *mem = malloc(sizeof(Msg)); Msg *g_msg = (Msg *)mem; int i; for(i=0;i<Num;i++){ char *str = "this is st"; str[11] = dex+48; str[12] = 0; strcpy(g_msg->context[i],str); } return mem;}int recv_sock_set(UINT16 PORT){ int sock_fd = socket(AF_INET,SOCK_DGRAM,0); if(sock_fd == -1){ perror("socket "); exit(1); } struct sockaddr_in serv; bzero(&serv,sizeof(serv)); serv.sin_family = AF_INET; serv.sin_addr.s_addr = htonl(INADDR_ANY); //inet_addr(""); serv.sin_port = htons(PORT); if(bind(sock_fd,(struct sockaddr *)&serv, sizeof(serv)) == -1){ perror("bind "); exit(1); } return sock_fd;}struct sockaddr_in send_sock_set(char *IP, UINT16 PORT){ struct sockaddr_in send; bzero(&send,sizeof(send)); send.sin_family = AF_INET; send.sin_addr.s_addr = inet_addr(IP); send.sin_port = htons(PORT); return send;}void handler(int arg){ printf("ctrl c finish process.\n"); exit(0);}
main.c
#include "../inc/common.h"extern void *st1_thread_run(void *args);extern void *st2_thread_run(void *args);extern void *st3_thread_run(void *args);extern void *rt_thread_run(void *args);int main(){ printf("main process start.\n"); signal(SIGINT,handler); pthread_t st1, st2, st3, st4; char *sendto_IP = "10.21.100.152"; UINT16 PORT = 9000; g_sendto = send_sock_set(sendto_IP,PORT); g_rt = create_pthread(90,SCHED_FIFO, TASK_JOIN,rt_thread_run,"rt_thread_run"); /*在本地实验,如果三个发送数据的线程优先级是一样的,那么第一个线程在后期争夺资源不如另外两个,所以将其调高了一点*/ g_st1 = create_pthread(91,SCHED_FIFO, TASK_JOIN,st1_thread_run,"st1_thread_run"); g_st2 = create_pthread(92,SCHED_FIFO, TASK_JOIN,st2_thread_run,"st2_thread_run"); g_st3 = create_pthread(92,SCHED_FIFO, TASK_JOIN,st3_thread_run,"st3_thread_run"); if(g_rt > 0)pthread_join(g_rt, NULL); /* 等待st1线程结束 */ else printf("create thread rt failed.\n"); exit(0);}
rt.c
#include "../inc/common.h"void *rt_thread_run(void *args){ printf("rt thread start work!\n"); g_rt_recv_sock = recv_sock_set(9000); void *get_msg = malloc(Len); if(get_msg == NULL){ perror("get_msg malloc "); exit(1); } while(1){ int recv_len = sizeof(g_recvfr); int ret = recvfrom(g_rt_recv_sock,get_msg,Len,0,(struct sockaddr*)&g_recvfr,&recv_len); if(ret > 0){ printf("%s\n",(char *)get_msg); } else printf("here is no data.\n"); } if(get_msg) free(get_msg); return NULL;}
st1.c
#include "../inc/common.h"void *st1_thread_run(void *args){ printf("st1 thread start work!\n"); //void *msg = msg_malloc((UINT8)1); char *get_msg = "this is st1 msg."; g_st1 = socket(AF_INET,SOCK_DGRAM,0); if(g_st1 == -1){ perror("socket "); exit(1); } while(1){ int i; /* Msg *send_msg = (Msg *)msg; for(i=0;i<Num;i++){ sendto(g_st1,send_msg->context[i],strlen(send_msg->context[i]),0, (struct sockaddr *)&g_sendto,sizeof(g_sendto)); }*/ int ret = sendto(g_st1,get_msg,strlen(get_msg),0,(struct sockaddr *)&g_sendto,sizeof(g_sendto)); if(ret <= 0){ perror("st1 send to "); } sleep(1); //send_msg = NULL; } return NULL;}
st2.c
#include "../inc/common.h"void *st2_thread_run(void *args){ printf("st2 thread start work!\n"); char *get_msg = "this is st2 msg."; g_st2 = socket(AF_INET,SOCK_DGRAM,0); if(g_st2 == -1){ perror("socket "); exit(1); } while(1){ int i; int ret = sendto(g_st2,get_msg,strlen(get_msg),0,(struct sockaddr *)&g_sendto, sizeof(g_sendto)); if(ret <= 0){ perror("st2 send to "); } sleep(1); } return NULL;}
st3.c
#include "../inc/common.h"void *st3_thread_run(void *args){ printf("st3 thread start work!\n"); char *get_msg = "this is st3 msg."; g_st3 = socket(AF_INET,SOCK_DGRAM,0); if(g_st3 == -1){ perror("socket "); exit(1); } while(1){ int i; int ret = sendto(g_st3,get_msg,strlen(get_msg),0,(struct sockaddr *)&g_sendto, sizeof(g_sendto)); if(ret <= 0){ perror("st3 send to "); } sleep(1); } return NULL;}
/pthread_data_transfer/makefile
PWD := $(shell pwd)IncDir := $(PWD)/../incINCLUDE_H_DIR := $(IncDir)DEBUG := -gMAIN := $(PWD)/srcMAIN_OBJ := $(MAIN)/*.o.PHONY:all all:lib $(CC) -o main $(MAIN_OBJ) -lm -lpthread -lrt .PHONY:liblib: $(MAKE) -C $(MAIN).PHONY:cleanclean: make clean -C $(MAIN) rm -f *.o *.a
/pthread_data_transfer/src/makefile
# source fileC_SOURCE := $(shell find -name '*.c')#Get object file generated by C source fileC_OBJS := $(subst .c,.o,$(C_SOURCE))#Get dependent file DEPS := $(subst .o,.d,$(C_OBJS)).PHONY:allall:$(C_OBJS)$(C_OBJS):%.o:%.c $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ifneq "$(MAKECMDGOALS)" "clean"-include $(DEPS)endif%.d:%.c $(CC) -M $(CFLAGS) $< > $@.$$$$;\ sed 's,$(subst .c,.o,$(notdir $<)),$(subst .c,.o,$<) $@,g' < $@.$$$$ > $@;\ rm -f $@.$$$$.PHONY:cleanclean: rm -rf *.o *.a *.d
得到的结果 (用root: ./main > read):
main process start.rt thread start work!st1 thread start work!this is st1 msg.st2 thread start work!this is st2 msg.st3 thread start work!this is st3 msg.this is st2 msg.this is st3 msg.this is st1 msg.this is st2 msg.this is st3 msg.this is st1 msg.this is st3 msg.this is st2 msg.this is st1 msg.this is st3 msg.this is st2 msg.this is st1 msg.ctrl c finish process.
0 0
- 简单的多线程数据传输
- 实现一个简单的多线程数据传输和文件传输
- TLV-简单的数据传输协议
- 简单实现一种经典的数据传输模型
- 简单的ajax数据传输和获取例子
- UDP试下数据传输 简单的聊天
- TCP协议实现数据传输的简单案例
- TCP连接的两种简单的数据传输方式
- Android与服务端的Socket连接实现简单数据传输
- 最简单的多线程
- 简单的多线程程序
- 简单的多线程
- c#简单的多线程
- 简单的多线程
- 简单的多线程示例
- C#简单的多线程
- 一个简单的多线程
- 简单的多线程
- QWidget无边框无标题栏窗体 可拖动可拉伸
- HDU3694 Fermat Point in Quadrangle 多边形费马点结论
- 一起学Google Daydream VR开发,快速入门开发基础教程二:Android端开发环境配置二
- 链表(10月3号学习总结)
- POJ 1523 SPF(无向图求割点,去割点形成子图数)
- 简单的多线程数据传输
- usaco 1.1 PROB Greedy Gift Givers 解题报告
- Java-获取网络资源大小
- 基于RollPagerView实现图片轮播功能
- Redis 一:Linux下 安装Redis并配置服务
- Java + 对象的聚合例子(计算三角形、圆形的面积)
- 用递归函数实现字符串反向输出
- PHP Webservice简单实例
- core_animation_lesson0