linux函数封装,linux Epoll 发送函数的封装问题…

大概流程就是:main.c 主文件运行后,接受客户端连接,当客户端发相应命令过来后,在tcp.c 文件中解析后,调用function.c文件中的处理函数:Receive_Process()。

原来我的想法是,在function处理完成后,通过Receive_Process()函数再把结果返回,

void Receive_Process(int conn_fd,unsigned char*  buff_r,unsigned char*  buff_w)

如果这样的话,就没这些问题了,处理的结果,我在tcp.c文件中,通过 “unsigned char*  buff_w” 可以拿到,送给PC就完事了。

现在同事要求不这么干,即不通过Receive_Process()进、出方式,把结果返回。而是要在fuction.c中(当然也可能其他文件中可以调用发送函数,把结果送给PC)把结果直接送给PC端…

(在另个帖子里可能没描述清楚)

主文件:

主要就是网上找到一段代码,简单调整了一下。

#include "tcp.h"

int main(int argc, char * argv[])

{

tcp_initialize();

epoll_fd_tcp=create_epoll_tcp(MAX_EVENTS_TCP);

while(1)

{

do_process_tcp_nowhile();

sleep(1);

}

}

处理文件:function.c

#include "function.h"

void Receive_Process(int conn_fd,unsigned char*  buff_r,unsigned char*  buff_w)

{

unsigned char CmdKey;

unsigned char length;

int len,i;

len = buff_r[1];

CmdKey = buff_r[2];

printf("packet len is : %02X\n",buff_r[1]);

printf("cmdkey is : %02X\n",buff_r[2]);

for(i=0;i

buff_r[i]=buff_r[i+1];

for(i=0;i

printf("%02X ",buff_r[i]);

printf("\n");

switch(CmdKey)

{

case 0x02:

//write_spi_arm_to_fpga_array(5,buff_r,buff_w);

// 根据命令,与FPGA交互后,将返回结果送给PC端,下面是模拟的数据。

buff_w[0]=0x08;

buff_w[1]=0x03;

buff_w[2]=0x8c;

buff_w[3]=0x00;

buff_w[4]=0x00;

//send to pc

tcp_send_data_to_pc(5 buff_w);

// 无发完成发送任务,这个函数只能在tcp.c文件中能正常,出了tcp.c文件就不行了。

printf("CMD_GET_VERSION OK \n");

break;

default:

break;

}

}

TCP文件: tcp.c

#include "tcp.h"

struct epoll_event events[MAX_EVENTS_TCP];// 事件监听队列

int server_sock_fd_tcp;// 服务器端套接字

int client_sock_fd_tcp;// 客户端套接字

int nfds_tcp;// epoll监听事件发生的个数

int len_recv_data_tcp;

struct sockaddr_in host_addr_tcp;   // 服务器网络地址结构体

struct sockaddr_in remote_addr_tcp; // 客户端网络地址结构体

int sin_size;

unsigned char send_data_buffer_size_tcp[BUFFER_SIZE_TCP];  // 数据传送的缓冲区

unsigned char retn_data_buffer_size_tcp[BUFFER_SIZE_TCP];

int m=0;

int len;

//设置句柄为非阻塞方式

int setnonblocking(int sockfd)

{

if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)

{

return -1;

}

return 0;

}

int tcp_send_data_to_pc(int len,char* buffer)

{

printf("in while n == %d \n",n);

send(events[n].data.fd,buffer,4,0);

ev.events = EPOLLIN;

ev.data.fd = events[n].data.fd;

epoll_ctl(epoll_fd_tcp, EPOLL_CTL_MOD, ev.data.fd, &ev);

}

void tcp_initialize()

{

struct rlimit rt;

/* 设置每个进程允许打开的最大文件数 */

rt.rlim_max = rt.rlim_cur = 1024;

if (setrlimit(RLIMIT_NOFILE, &rt) == -1)

{

perror("setrlimit");

exit(1);

}

else

{

printf("setrlimit ok! \n");

}

// 创建服务器端套接字--IPv4协议,面向连接通信,TCP协议

if((server_sock_fd_tcp=socket(PF_INET,SOCK_STREAM,0))<0)

{

perror("socket");

//return 1;

}

else

{

printf("Tcp server socket ok...\n");

}

// 设置 socket属性,端口可以重用

int opt=SO_REUSEADDR;

setsockopt(server_sock_fd_tcp,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

setnonblocking(server_sock_fd_tcp);

memset(&host_addr_tcp,0,sizeof(host_addr_tcp)); // 数据初始化--清零

host_addr_tcp.sin_family=PF_INET; // 设置为IP通信

host_addr_tcp.sin_addr.s_addr=inet_addr(HOST_IP_ADDRESS_TCP);// 服务器IP地址--允许连接到所有本地地址上

host_addr_tcp.sin_port=htons(HOST_PORT_TCP); // 服务器端口号

// 将套接字绑定到服务器的网络地址上

if (bind(server_sock_fd_tcp,(struct sockaddr *)&host_addr_tcp,sizeof(struct sockaddr))<0)

{

perror("bind");

//return 1;

}

else

{

printf("Tcp server bind ok...\n");

printf("IP  : %s   \n", inet_ntoa(host_addr_tcp.sin_addr));

printf("port: %d \n",ntohs(host_addr_tcp.sin_port));

}

// 监听连接请求--监听队列长度为5

listen(server_sock_fd_tcp,64);

sin_size=sizeof(struct sockaddr_in);

}

// 创建一个epoll句柄

int create_epoll_tcp(unsigned int event_num)

{

int epoll_fd;

epoll_fd=epoll_create(event_num);

if(epoll_fd==-1)

{

perror("epoll_create failed");

}

ev.events=EPOLLIN | EPOLLET;

ev.data.fd=server_sock_fd_tcp;

// 向epoll注册server_sockfd监听事件

if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,server_sock_fd_tcp,&ev)==-1)

{

perror("epll_ctl:server_sock_fd_tcp register failed");

}

else

{

printf("socket adding in  epoll success! \n");

}

return epoll_fd;

}

void do_process_tcp_nowhile()

{

// 等待事件发生

nfds_tcp=epoll_wait(epoll_fd_tcp,events,1024,-1);

if(nfds_tcp==-1)

{

perror("start epoll_wait failed");

//exit(EXIT_FAILURE);

}

else

{

printf(" epoll nfds_tcp = %d   \n",nfds_tcp);

}

for(n=0;n

{

printf(" for loop epoll nfds_tcp = %d   \n",nfds_tcp);

// 客户端有新的连接请求

if(events[n].data.fd == server_sock_fd_tcp)

{

// 等待客户端连接请求到达

if((client_sock_fd_tcp=accept(server_sock_fd_tcp,(struct sockaddr *)&remote_addr_tcp,&sin_size))<0)

{

perror("accept client_sock_fd_tcp failed");

exit(EXIT_FAILURE);

}

// 向epoll注册client_sockfd监听事件

setnonblocking(client_sock_fd_tcp);

ev.events=EPOLLIN | EPOLLET;

ev.data.fd=client_sock_fd_tcp;

if(epoll_ctl(epoll_fd_tcp,EPOLL_CTL_ADD,client_sock_fd_tcp,&ev)==-1)

{

perror("epoll_ctl:client_sock_fd_tcp register failed");

}

printf("accept client %s\n",inet_ntoa(remote_addr_tcp.sin_addr));

}

else if(events[n].events & EPOLLIN)

{

// 客户端有数据发送过来

sprintf(send_data_buffer_size_tcp,"");

//sin_size=sizeof(remote_addr_tcp);

len_recv_data_tcp=recv(events[n].data.fd,send_data_buffer_size_tcp,BUFFER_SIZE_TCP,0);

if(len_recv_data_tcp<=0)

{

printf("close id is : %d \n",events[n].data.fd);

if(epoll_ctl(epoll_fd_tcp,EPOLL_CTL_DEL,events[n].data.fd,&ev)==0)

{

printf("delete ok \n");

close(events[n].data.fd);

}

else

{

printf("delete error \n");

}

}

else

{//处理PC来的命令包,,调用fuction.c文件中的 Receive_Process()函数

Receive_Process(4,send_data_buffer_size_tcp,retn_data_buffer_size_tcp);

ev.data.fd = events[n].data.fd;

ev.events = EPOLLOUT|EPOLLET;

epoll_ctl(epoll_fd_tcp, EPOLL_CTL_MOD, events[n].data.fd, &ev);

}

}

else if(events[n].events & EPOLLOUT)//发送

{

tcp_send_data_to_pc(4,send_data_buffer_size_tcp);//这个地方就正常

}

}

if(server_sock_fd_tcp>0)

{

printf("socket close \n");

shutdown(server_sock_fd_tcp,SHUT_RDWR);

close(server_sock_fd_tcp);

}

}

tcp.h头文件

#include 

#include 

#include 

#include 

#include 

#define BUFFER_SIZE_TCP 40

#define MAX_EVENTS_TCP 10

#define HOST_IP_ADDRESS_TCP "192.168.1.200"

#define HOST_PORT_TCP 4530

int n;

struct epoll_event ev;// epoll事件结构体

int epoll_fd_tcp;

int tcp_send_data_to_pc(int len,char* buffer);

void tcp_initialize();

int create_epoll_tcp(unsigned int event_num);

void do_process_tcp_nowhile();

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值