亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3304 | 回復(fù): 6
打印 上一主題 下一主題

[C] linux epoll 發(fā)送函數(shù)封裝問題請(qǐng)教... [復(fù)制鏈接]

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2015-04-18 10:00 |只看該作者 |倒序?yàn)g覽

大概流程就是:main.c 主文件運(yùn)行后,接受客戶端連接,當(dāng)客戶端發(fā)相應(yīng)命令過來后,在tcp.c 文件中解析后,調(diào)用function.c文件中的處理函數(shù):Receive_Process()。
原來我的想法是,在function處理完成后,通過Receive_Process()函數(shù)再把結(jié)果返回,
[code=c]void Receive_Process(int conn_fd,unsigned char*  buff_r,unsigned char*  buff_w)[/code]
如果這樣的話,就沒這些問題了,處理的結(jié)果,我在tcp.c文件中,通過 “unsigned char*  buff_w” 可以拿到,送給PC就完事了。

現(xiàn)在同事要求不這么干,即不通過Receive_Process()進(jìn)、出方式,把結(jié)果返回。而是要在fuction.c中(當(dāng)然也可能其他文件中可以調(diào)用發(fā)送函數(shù),把結(jié)果送給PC)把結(jié)果直接送給PC端...


(在另個(gè)帖子里可能沒描述清楚)

主文件:
主要就是網(wǎng)上找到一段代碼,簡(jiǎn)單調(diào)整了一下。

  1. #include "tcp.h"
  2. int main(int argc, char * argv[])   
  3. {       
  4.                 tcp_initialize();
  5.                 epoll_fd_tcp=create_epoll_tcp(MAX_EVENTS_TCP);         
  6.           while(1)
  7.           {
  8.                    do_process_tcp_nowhile();
  9.                    sleep(1);
  10.           }         
  11. }  
復(fù)制代碼
處理文件:function.c

  1. #include "function.h"

  2. void Receive_Process(int conn_fd,unsigned char*  buff_r,unsigned char*  buff_w)
  3. {
  4.         unsigned char CmdKey;
  5.         unsigned char length;
  6.         int len,i;
  7.   len = buff_r[1];
  8.         CmdKey = buff_r[2];       
  9.         printf("packet len is : %02X\n",buff_r[1]);
  10.         printf("cmdkey is : %02X\n",buff_r[2]);
  11.         for(i=0;i<len;i++)
  12.                      buff_r[i]=buff_r[i+1];
  13.              for(i=0;i<len;i++)
  14.                      printf("%02X ",buff_r[i]);
  15.   printf("\n");
  16. switch(CmdKey)
  17.         {                               
  18.                 case 0x02:
  19.                         //write_spi_arm_to_fpga_array(5,buff_r,buff_w);
  20.                      [color=#FF0000]  // 根據(jù)命令,與FPGA交互后,將返回結(jié)果送給PC端,下面是模擬的數(shù)據(jù)。[/color]
  21.                         buff_w[0]=0x08;
  22.                         buff_w[1]=0x03;
  23.                         buff_w[2]=0x8c;
  24.                         buff_w[3]=0x00;
  25.                         buff_w[4]=0x00;
  26.                         //send to pc
  27.                        [color=#FF0000] tcp_send_data_to_pc(5 buff_w);[/color]
  28.                        // 無發(fā)完成發(fā)送任務(wù),這個(gè)函數(shù)只能在tcp.c文件中能正常,出了tcp.c文件就不行了。
  29.                         printf("CMD_GET_VERSION OK \n");               
  30.                         break;
  31.                 default:                                               
  32.                         break;
  33.         }               
  34. }
復(fù)制代碼
TCP文件: tcp.c

  1. #include "tcp.h"

  2. struct epoll_event events[MAX_EVENTS_TCP];// 事件監(jiān)聽隊(duì)列


  3. int server_sock_fd_tcp;// 服務(wù)器端套接字   
  4. int client_sock_fd_tcp;// 客戶端套接字      
  5. int nfds_tcp;// epoll監(jiān)聽事件發(fā)生的個(gè)數(shù)
  6. int len_recv_data_tcp;
  7. struct sockaddr_in host_addr_tcp;   // 服務(wù)器網(wǎng)絡(luò)地址結(jié)構(gòu)體   
  8. struct sockaddr_in remote_addr_tcp; // 客戶端網(wǎng)絡(luò)地址結(jié)構(gòu)體   
  9. int sin_size;   
  10. unsigned char send_data_buffer_size_tcp[BUFFER_SIZE_TCP];  // 數(shù)據(jù)傳送的緩沖區(qū)  
  11. unsigned char retn_data_buffer_size_tcp[BUFFER_SIZE_TCP];   
  12. int m=0;
  13. int len;
  14. //設(shè)置句柄為非阻塞方式
  15. int setnonblocking(int sockfd)  
  16. {  
  17. if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)  
  18. {  
  19.     return -1;  
  20. }  
  21.     return 0;  
  22. }

  23. int tcp_send_data_to_pc(int len,char* buffer)
  24. {       
  25.                 printf("in while n == %d \n",n);
  26.                 send(events[n].data.fd,buffer,4,0);               
  27.                 ev.events = EPOLLIN;
  28.                 ev.data.fd = events[n].data.fd;
  29.     epoll_ctl(epoll_fd_tcp, EPOLL_CTL_MOD, ev.data.fd, &ev);
  30. }

  31. void tcp_initialize()
  32. {
  33.     struct rlimit rt;
  34.    
  35.     /* 設(shè)置每個(gè)進(jìn)程允許打開的最大文件數(shù) */  
  36.     rt.rlim_max = rt.rlim_cur = 1024;  
  37.     if (setrlimit(RLIMIT_NOFILE, &rt) == -1)   
  38.                 {  
  39.         perror("setrlimit");  
  40.         exit(1);  
  41.     }  
  42.     else   
  43.     {  
  44.         printf("setrlimit ok! \n");  
  45.     }  
  46.    
  47.     // 創(chuàng)建服務(wù)器端套接字--IPv4協(xié)議,面向連接通信,TCP協(xié)議
  48.     if((server_sock_fd_tcp=socket(PF_INET,SOCK_STREAM,0))<0)   
  49.     {     
  50.         perror("socket");   
  51.         //return 1;   
  52.     }
  53.     else
  54.     {
  55.             printf("Tcp server socket ok...\n");
  56.     }
  57.            
  58.             // 設(shè)置 socket屬性,端口可以重用   
  59.   
  60.           int opt=SO_REUSEADDR;
  61.           setsockopt(server_sock_fd_tcp,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
  62.           setnonblocking(server_sock_fd_tcp);
  63.            
  64.     memset(&host_addr_tcp,0,sizeof(host_addr_tcp)); // 數(shù)據(jù)初始化--清零      
  65.     host_addr_tcp.sin_family=PF_INET; // 設(shè)置為IP通信   
  66.     host_addr_tcp.sin_addr.s_addr=inet_addr(HOST_IP_ADDRESS_TCP);// 服務(wù)器IP地址--允許連接到所有本地地址上   
  67.     host_addr_tcp.sin_port=htons(HOST_PORT_TCP); // 服務(wù)器端口號(hào)  
  68.    
  69.     // 將套接字綁定到服務(wù)器的網(wǎng)絡(luò)地址上
  70.     if (bind(server_sock_fd_tcp,(struct sockaddr *)&host_addr_tcp,sizeof(struct sockaddr))<0)   
  71.     {   
  72.         perror("bind");   
  73.         //return 1;   
  74.     }
  75.     else
  76.     {
  77.             printf("Tcp server bind ok...\n");
  78.             printf("IP  : %s   \n", inet_ntoa(host_addr_tcp.sin_addr));
  79.             printf("port: %d \n",ntohs(host_addr_tcp.sin_port));
  80.     }
  81.     // 監(jiān)聽連接請(qǐng)求--監(jiān)聽隊(duì)列長(zhǎng)度為5
  82.     listen(server_sock_fd_tcp,64);   
  83.     sin_size=sizeof(struct sockaddr_in);
  84.        
  85. }

  86. // 創(chuàng)建一個(gè)epoll句柄
  87. int create_epoll_tcp(unsigned int event_num)
  88.   {       
  89.           int epoll_fd;
  90.                 epoll_fd=epoll_create(event_num);
  91.                 if(epoll_fd==-1)
  92.                 {
  93.                         perror("epoll_create failed");                       
  94.                 }
  95.                 ev.events=EPOLLIN | EPOLLET;
  96.                 ev.data.fd=server_sock_fd_tcp;
  97.                 // 向epoll注冊(cè)server_sockfd監(jiān)聽事件
  98.                 if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,server_sock_fd_tcp,&ev)==-1)
  99.                 {
  100.                         perror("epll_ctl:server_sock_fd_tcp register failed");                       
  101.                 }
  102.                 else
  103.           {
  104.             printf("socket adding in  epoll success! \n");
  105.           }
  106.                 return epoll_fd;
  107. }

  108. void do_process_tcp_nowhile()
  109. {                         
  110.                         // 等待事件發(fā)生
  111.                         nfds_tcp=epoll_wait(epoll_fd_tcp,events,1024,-1);
  112.                         if(nfds_tcp==-1)
  113.                         {
  114.                                 perror("start epoll_wait failed");
  115.                                 //exit(EXIT_FAILURE);
  116.                         }
  117.                         else
  118.                         {
  119.                                         printf(" epoll nfds_tcp = %d   \n",nfds_tcp);
  120.                         }
  121.                        
  122.                         for(n=0;n<nfds_tcp;++n)
  123.                         {
  124.                                 printf(" for loop epoll nfds_tcp = %d   \n",nfds_tcp);
  125.                                 // 客戶端有新的連接請(qǐng)求
  126.                                 if(events[n].data.fd == server_sock_fd_tcp)
  127.                                 {
  128.                                         // 等待客戶端連接請(qǐng)求到達(dá)
  129.                       if((client_sock_fd_tcp=accept(server_sock_fd_tcp,(struct sockaddr *)&remote_addr_tcp,&sin_size))<0)
  130.                                         {   
  131.                                                 perror("accept client_sock_fd_tcp failed");   
  132.                                                 exit(EXIT_FAILURE);
  133.                                         }
  134.                                         // 向epoll注冊(cè)client_sockfd監(jiān)聽事件
  135.                                         setnonblocking(client_sock_fd_tcp);
  136.                                         ev.events=EPOLLIN | EPOLLET;
  137.                                         ev.data.fd=client_sock_fd_tcp;
  138.                                         if(epoll_ctl(epoll_fd_tcp,EPOLL_CTL_ADD,client_sock_fd_tcp,&ev)==-1)
  139.                                         {
  140.                                                 perror("epoll_ctl:client_sock_fd_tcp register failed");                                               
  141.                                         }
  142.                                         printf("accept client %s\n",inet_ntoa(remote_addr_tcp.sin_addr));                                               
  143.                                 }
  144.                                 else if(events[n].events & EPOLLIN)
  145.                                 {
  146.                                         // 客戶端有數(shù)據(jù)發(fā)送過來
  147.                                         sprintf(send_data_buffer_size_tcp,"");
  148.                                         //sin_size=sizeof(remote_addr_tcp);
  149.                                
  150.                                         len_recv_data_tcp=recv(events[n].data.fd,send_data_buffer_size_tcp,BUFFER_SIZE_TCP,0);
  151.                                         if(len_recv_data_tcp<=0)
  152.                                         {
  153.                                                 printf("close id is : %d \n",events[n].data.fd);                                       
  154.                                                 if(epoll_ctl(epoll_fd_tcp,EPOLL_CTL_DEL,events[n].data.fd,&ev)==0)
  155.                                                 {
  156.                                                         printf("delete ok \n");
  157.                                                         close(events[n].data.fd);
  158.                                                 }
  159.                                                 else
  160.                                                 {
  161.                                                         printf("delete error \n");
  162.                                                 }
  163.                                         }
  164.                                         else
  165.                                         {//[color=#FF0000]處理PC來的命令包,,調(diào)用fuction.c文件中的 Receive_Process()函數(shù)[/color]
  166.                                      Receive_Process(4,send_data_buffer_size_tcp,retn_data_buffer_size_tcp);
  167.                                     
  168.                                                 ev.data.fd = events[n].data.fd;
  169.             ev.events = EPOLLOUT|EPOLLET;
  170.             epoll_ctl(epoll_fd_tcp, EPOLL_CTL_MOD, events[n].data.fd, &ev);                                                       
  171.                                         }
  172.                                 }
  173.                                 else if(events[n].events & EPOLLOUT)//發(fā)送
  174.                                 {                                       
  175.                                         tcp_send_data_to_pc(4,send_data_buffer_size_tcp);        [color=#FF0000]//這個(gè)地方就正常        [/color]                       
  176.                                 }
  177.                         }                       
  178.                
  179.                 if(server_sock_fd_tcp>0)
  180.                 {
  181.                         printf("socket close \n");
  182.                         shutdown(server_sock_fd_tcp,SHUT_RDWR);
  183.                         close(server_sock_fd_tcp);
  184.                 }
  185.                
  186. }
復(fù)制代碼
tcp.h頭文件

  1. #include <arpa/inet.h>  
  2. #include <fcntl.h>  
  3. #include <sys/epoll.h>  
  4. #include <sys/time.h>  
  5. #include <sys/resource.h>  

  6. #define BUFFER_SIZE_TCP 40
  7. #define MAX_EVENTS_TCP 10
  8. #define HOST_IP_ADDRESS_TCP "192.168.1.200"
  9. #define HOST_PORT_TCP 4530

  10. int n;
  11. struct epoll_event ev;// epoll事件結(jié)構(gòu)體

  12. int epoll_fd_tcp;
  13. int tcp_send_data_to_pc(int len,char* buffer);
  14. void tcp_initialize();
  15. int create_epoll_tcp(unsigned int event_num);
  16. void do_process_tcp_nowhile();

復(fù)制代碼

論壇徽章:
15
射手座
日期:2014-11-29 19:22:4915-16賽季CBA聯(lián)賽之青島
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16賽季CBA聯(lián)賽之四川
日期:2017-02-07 21:08:572015年亞冠紀(jì)念徽章
日期:2015-11-06 12:31:58每日論壇發(fā)貼之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-07-12 22:20:002015亞冠之浦和紅鉆
日期:2015-07-08 10:10:132015亞冠之大阪鋼巴
日期:2015-06-29 11:21:122015亞冠之廣州恒大
日期:2015-05-22 21:55:412015年亞洲杯之伊朗
日期:2015-04-10 16:28:25
2 [報(bào)告]
發(fā)表于 2015-04-20 11:00 |只看該作者
本帖最后由 yulihua49 于 2015-04-20 12:00 編輯
sasinop 發(fā)表于 2015-04-18 10:00
大概流程就是:main.c 主文件運(yùn)行后,接受客戶端連接,當(dāng)客戶端發(fā)相應(yīng)命令過來后,在tcp.c 文件中解析后, ...

這算是啥封裝哦!
根據(jù)你的題目,就是要寫一個(gè)函數(shù),利用epoll進(jìn)行異步操作,讓應(yīng)用可以使用這個(gè)函數(shù)發(fā)送任何信息,屏蔽epoll的一切特性。
為完成這個(gè)任務(wù),可能需要一些初始化工作。
http://72891.cn/thread-4174032-1-2.html
看看3樓那個(gè),才是“封裝”,應(yīng)用只要調(diào)用那個(gè)函數(shù)即可發(fā)送任意數(shù)據(jù),異步操作,epoll,線程池,協(xié)程之類的細(xì)節(jié)完全屏蔽。
那是一個(gè)實(shí)際可以工作的程序,不是個(gè)demo或者作業(yè)什么的。沒有給出初始化過程。

那個(gè)例子表示了什么是“封裝”。怎樣封裝的,需要對(duì)do_event()進(jìn)行逐層展開。
你的例子大量使用全局變量,無法支持多線程。

你同事的要求是對(duì)的,你要寫一個(gè)通用的發(fā)送函數(shù),供各種場(chǎng)合用。很可能還需要個(gè)接收函數(shù)。
你的那么多行程序沒必要提供,自己留著用,只需對(duì)外提供:
初始化(構(gòu)造函數(shù)),善后(析構(gòu)函數(shù)),發(fā)送函數(shù),接收函數(shù)即可。

人們不關(guān)心你的process,無數(shù)的應(yīng)用邏輯,可以有無數(shù)的process,他們的共同需求是在網(wǎng)上收發(fā)數(shù)據(jù)。
他們希望唯一的線程(你那個(gè)是單線程的)不要耽誤在等待IO上,又不希望復(fù)雜的異步邏輯把應(yīng)用邏輯攪得一塌糊涂。
于是,AIO -- 協(xié)程就產(chǎn)生了。

你可以拿我那個(gè)程序問問同事,要的是不是這個(gè)東西,然后再說怎么做。

論壇徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46處女座
日期:2013-10-24 14:25:01酉雞
日期:2014-04-07 11:54:15
3 [報(bào)告]
發(fā)表于 2015-04-21 11:30 |只看該作者
封裝性太差了,應(yīng)該先將epoll細(xì)節(jié)封裝起來,之后再封裝tcp/udp,這樣做業(yè)務(wù)才會(huì)變簡(jiǎn)單。

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
4 [報(bào)告]
發(fā)表于 2015-04-21 16:57 |只看該作者
回復(fù) 2# yulihua49

謝謝呀

沒法測(cè)試你的哪個(gè)函數(shù)


不知道你那個(gè)封裝的函數(shù),是不是在一個(gè)工程里,有N多個(gè)文件時(shí),隨意在某個(gè)文件里都可以調(diào)用,都可以來發(fā)送數(shù)據(jù)給客戶端?






   

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
5 [報(bào)告]
發(fā)表于 2015-04-21 17:03 |只看該作者
你同事的要求是對(duì)的,你要寫一個(gè)通用的發(fā)送函數(shù),供各種場(chǎng)合用。很可能還需要個(gè)接收函數(shù)。


這樣好么?

一個(gè)函數(shù)比如,do (in,out) 這樣, 命令和結(jié)果一個(gè)函數(shù)扎口不好在什么地方呢?

同事那種要求:do(in), 只進(jìn)命令,,結(jié)果 send(out),要在不同的文件,不同的命令分支調(diào)用,處理完成后,就直接把結(jié)果送出去了... 難道這樣好?

不解,請(qǐng)賜教呀

論壇徽章:
15
射手座
日期:2014-11-29 19:22:4915-16賽季CBA聯(lián)賽之青島
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16賽季CBA聯(lián)賽之四川
日期:2017-02-07 21:08:572015年亞冠紀(jì)念徽章
日期:2015-11-06 12:31:58每日論壇發(fā)貼之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-07-12 22:20:002015亞冠之浦和紅鉆
日期:2015-07-08 10:10:132015亞冠之大阪鋼巴
日期:2015-06-29 11:21:122015亞冠之廣州恒大
日期:2015-05-22 21:55:412015年亞洲杯之伊朗
日期:2015-04-10 16:28:25
6 [報(bào)告]
發(fā)表于 2015-04-21 20:23 |只看該作者
sasinop 發(fā)表于 2015-04-21 16:57
回復(fù) 2# yulihua49

謝謝呀

那個(gè)函數(shù)僅供學(xué)習(xí),它是交易中間件的一部分,整個(gè)系統(tǒng)太大了,要下載整個(gè)中間件的源碼。
你用那個(gè)函數(shù),看懂過程和概念即可,按這個(gè)思路寫自己的東西。

論壇徽章:
15
射手座
日期:2014-11-29 19:22:4915-16賽季CBA聯(lián)賽之青島
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16賽季CBA聯(lián)賽之四川
日期:2017-02-07 21:08:572015年亞冠紀(jì)念徽章
日期:2015-11-06 12:31:58每日論壇發(fā)貼之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-07-12 22:20:002015亞冠之浦和紅鉆
日期:2015-07-08 10:10:132015亞冠之大阪鋼巴
日期:2015-06-29 11:21:122015亞冠之廣州恒大
日期:2015-05-22 21:55:412015年亞洲杯之伊朗
日期:2015-04-10 16:28:25
7 [報(bào)告]
發(fā)表于 2015-04-21 20:26 |只看該作者
本帖最后由 yulihua49 于 2015-04-21 20:53 編輯
sasinop 發(fā)表于 2015-04-21 17:03
這樣好么?

一個(gè)函數(shù)比如,do (in,out) 這樣, 命令和結(jié)果一個(gè)函數(shù)扎口不好在什么地方呢?

in和out還是要分開的,比如有時(shí)是一進(jìn)一出,有時(shí)是幾進(jìn)一出,一進(jìn)幾出,只進(jìn)不出。。。。
還有,正常出,錯(cuò)誤(異常)出等等,業(yè)務(wù)邏輯什么需求都有。

所以,你只要提供 in,out就可以了,何時(shí)in,何時(shí)out,它們之前,之間,之后做了什么你就不必管了。

就像我那個(gè)程序,只管發(fā)送N字節(jié)到socket。之前,要填充包頭,包體要壓縮,加密,校驗(yàn)。。。
之后要?dú)w還資源(內(nèi)存和連接池),寫日志。。。。。。這些你管的著嗎?

你寫了個(gè)in,out,把AIO,epoll...都埋藏在這兩個(gè)函數(shù)里,外邊那些作業(yè)就容易多了。
看我的程序,知道怎么埋藏,這可是個(gè)大學(xué)問。

對(duì)了,那個(gè)windoze也很會(huì)埋,我還是跟他學(xué)的。不過他的代碼很多,你也可以用他的那個(gè)fiberized .IO, C++  的。
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP