epoll中的data联合体怎样使用的问题
2016-09-08 15:16
253 查看
1、epoll结构体的成员data其实是一个结构体,具体如下:
typedef union epoll_data
{
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event
{
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
那么我们在编程时就不应该同事使用epoll_data联合体中的两个成员,比如,有时为了方便确定那个描述符就绪,以及获取自己定义的一些内容,我们常常ptr和fd同事使用,结果发现程序会崩溃。比如下面一段文字是overstack上面的一个提问:
I am having an increasingly hard time using the void *ptr in the epoll_event. I
can just link this to a struct? For example, can I do something like this? Because I am trying todo something like this but it does not work, the first loop on the listen socket is good, but after another event comes in it crashes. Can someone help me out
in understanding how to use data.ptr?
struct client {
int fd;
int connection_status;
};
struct epoll_event *events = NULL;
struct epoll_event ev;
struct client *c = new client;
struct client *event_c = NULL;
c.fd = (socket);
int efd = epoll_create1(0);
ev.data.fd = c.fd; //使用了fd
ev.events = EPOLLIN;
ev.data.ptr = c;//又使用了ptr,所以肯定有问题
epoll_ctl ( efd , EPOLL_CTL_ADD , c.fd , &ev );
events = (struct epoll_event*)calloc ( XXX , sizeof event );
while(1) {
int n = epoll_wait ( efd , events , XXX , -1 );
for ( int i = 0 ; i < n ; i++ ) {
event_c = (struct client*) events[i].data.ptr;
cout << "SOCKET: " << event_c->fd << endl;
if (c->fd == events[i].data.fd ) {
struct client *new_c = new client;
struct epoll_event new_ev;
struct sockaddr inaddr;
sockletn_t in_len;
int nfd = accept ( c->fd , &inaddr , &in_len );
/* make socket non-blocking ... / error checking */
new_c->fd = nfd;
new_c->connection_status = 1;
new_ev.data.fd = nfd;
new_ev.events = EPOLLIN;
new_ev.data.ptr = client;//应该是:<span style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;">new_c</span>
int r = epoll_ctl ( efd , EPOLL_CTL_ADD , nfd , &new_ev );
continue;
} else {
ssize_t count;
char buf[512];
int count = read ( events[i].data.fd , buf , sizeof buf );
// ... error checking blah blah blah
int rc = write ( 1 , buf , count );
}
}
}
下面是回答:
The
well and only link pointer to the struct in the
of the
This way when you get back your pointer then get the
it for further use.
解决方法:将fd等所有我们感兴趣的东西全部放到一个结构体st里面,然后将结构体指针pst赋值给ptr,当epoll_wait()返回时,先:ptr=(st*)((evs[index].data.ptr)),根据pst里面的fd就可以知道是哪个套接字发送过来的数据了。然后再条用recv(ptr->fd)等套接字函数收数据。
4000
typedef union epoll_data
{
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event
{
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
那么我们在编程时就不应该同事使用epoll_data联合体中的两个成员,比如,有时为了方便确定那个描述符就绪,以及获取自己定义的一些内容,我们常常ptr和fd同事使用,结果发现程序会崩溃。比如下面一段文字是overstack上面的一个提问:
I am having an increasingly hard time using the void *ptr in the epoll_event. I
can just link this to a struct? For example, can I do something like this? Because I am trying todo something like this but it does not work, the first loop on the listen socket is good, but after another event comes in it crashes. Can someone help me out
in understanding how to use data.ptr?
struct client {
int fd;
int connection_status;
};
struct epoll_event *events = NULL;
struct epoll_event ev;
struct client *c = new client;
struct client *event_c = NULL;
c.fd = (socket);
int efd = epoll_create1(0);
ev.data.fd = c.fd; //使用了fd
ev.events = EPOLLIN;
ev.data.ptr = c;//又使用了ptr,所以肯定有问题
epoll_ctl ( efd , EPOLL_CTL_ADD , c.fd , &ev );
events = (struct epoll_event*)calloc ( XXX , sizeof event );
while(1) {
int n = epoll_wait ( efd , events , XXX , -1 );
for ( int i = 0 ; i < n ; i++ ) {
event_c = (struct client*) events[i].data.ptr;
cout << "SOCKET: " << event_c->fd << endl;
if (c->fd == events[i].data.fd ) {
struct client *new_c = new client;
struct epoll_event new_ev;
struct sockaddr inaddr;
sockletn_t in_len;
int nfd = accept ( c->fd , &inaddr , &in_len );
/* make socket non-blocking ... / error checking */
new_c->fd = nfd;
new_c->connection_status = 1;
new_ev.data.fd = nfd;
new_ev.events = EPOLLIN;
new_ev.data.ptr = client;//应该是:<span style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;">new_c</span>
int r = epoll_ctl ( efd , EPOLL_CTL_ADD , nfd , &new_ev );
continue;
} else {
ssize_t count;
char buf[512];
int count = read ( events[i].data.fd , buf , sizeof buf );
// ... error checking blah blah blah
int rc = write ( 1 , buf , count );
}
}
}
下面是回答:
The
void *ptrand
int fdboth are inside a union inside the
struct epoll_event. You should use either of them not both. Hence in your struct, add the field for
fdas
well and only link pointer to the struct in the
ptrfield
of the
epoll_event.
This way when you get back your pointer then get the
fdfrom
it for further use.
解决方法:将fd等所有我们感兴趣的东西全部放到一个结构体st里面,然后将结构体指针pst赋值给ptr,当epoll_wait()返回时,先:ptr=(st*)((evs[index].data.ptr)),根据pst里面的fd就可以知道是哪个套接字发送过来的数据了。然后再条用recv(ptr->fd)等套接字函数收数据。
4000
相关文章推荐
- 怎样解决kodak扫描控件,在xp下使用出错的问题?2000是没有问题的
- 使用CachedRowSetDataProvider需要解决的问题
- 使用coredata导致的版本更新后程序crash的问题
- Aqua Data Studio 第一次使用遇到的问题(转自网络资料)
- JSP使用ENCTYPE="multipart/form-data"后request.getParameter无效问题Common-FileUpload组件解决方法
- 使用Data Access Application Block遇到的问题
- 问题小结(7)-sd卡和/data分区使用情况检测
- 【转】使用C#通过Oracle.DataAccess连接Oracle,部署时需要注意版本问题
- C# 使用SqlDataReader 注意问题
- 安卓开发中使用sqlite数据库时打不开data/data目录的问题解决
- 关于Data 控件的使用有关问题!
- asp.net mvc 2 简简单单做开发 使用DataContext扩展方法Find<TEntity>(TEntity obj) 遇到的问题
- 关于在linux下epoll的使用问题
- 关于dot Net的System.Data.OracleClient.dll的使用问题
- epoll使用的常见问题
- 怎样在SqlDataAdapter中通过Sqlcommand使用存储过程
- e.Item.DataItem使用问题
- .Net下使用System.Data.OracleClient出现“ORA-12154问题“TNS: 无法处理服务名”问题的解决
- 使用coredata导致的版本更新后程序crash的问题
- 问题小结(7)-sd卡和/data分区使用情况检测