思路如下:
部分結構體定義如下:
struct pakege{
unsigned short port;
unsigned short ipi_port;
unsigned int data_len;
unsigned int ipaddr;
unsigned int ipi_addr;
unsigned char data[BUF_LEN];
unsigned char r_flag;
};
分割
---------------------------------------------
struct eloop_sock
{
int active;
int sock_fd;
int s_fd;/*記錄服務器的fd*/
char c_flag;/*1 客戶端,0 服務器*/
char socket_type;/*0 tcp server 1 udp server*/
int (*handler)(struct eloop_sock *sock,pthread_t *pth_id);
int depth;
/*主機bind的ip和端口號*/
unsigned short port;
unsigned int ipaddr;
/*buf的兩個指針*/
int f_count;
int r_count;
int cli_count;
struct sockaddr_in *ClientAddr;
struct pakege **p_data;
struct list_head list;
pthread_mutex_t w_mutex;
pthread_mutex_t r_mutex;
pthread_cond_t check_cond;
struct eloop_sock *root;
pthread_t pth_id;
};
extern pthread_rwlock_t g_mutex;
struct eloop_data
{
int max_sock,reader_count;
int init;
struct list_head reader;//eloop_sock 鏈表頭
};
接口代碼如下:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
#include <netdb.h>
#include <errno.h>
#include "server.h"
#include "public.h"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
struct pakege{
unsigned short port;
unsigned short ipi_port;
unsigned int data_len;
unsigned int ipaddr;
unsigned int ipi_addr;
unsigned char data[BUF_LEN];
unsigned char r_flag;
};
pthread_t local_pth_id;
pthread_rwlock_t g_mutex;
int g_run = 0;
int need_exit_flag = 0;
int s_count = 0;
void ctrl_c_handler(int sign_num){
g_run = 1;
}
unsigned char RecvData(struct eloop_sock *sock,unsigned int fd){
int iSendLen;
int iRecvLen;
int AddrLen;
int i = 0,j = 0;
struct sockaddr_in tSocketClientAddr;
struct sockaddr_in localaddr;
struct eloop_sock *reader = NULL;
unsigned int d_port = 0;
unsigned int d_ip = 0;
AddrLen = sizeof(struct sockaddr);
if (sock->root) {/*tcp*/
reader = sock->root;
}
else {
reader = sock; /*udp*/
}
memset(&localaddr,0,AddrLen);
char cmbuf[100];
char buffer[BUF_LEN];
struct iovec iov[1];
iov[0].iov_base = reader->p_data[reader->f_count]->data;
iov[0].iov_len = sizeof(reader->p_data[reader->f_count]->data);
struct msghdr mh =
{
.msg_name = &localaddr,
.msg_namelen = sizeof(localaddr),
.msg_control = cmbuf,
.msg_controllen = sizeof(cmbuf),
.msg_iov=iov,
.msg_iovlen=1
};
iRecvLen = recvmsg(fd,&mh,0);
if(iRecvLen > 0){
//printf("Receive:%dByte\tThe Message Is:%s!\n",iRecvLen,reader->p_data[reader->f_count]->data);
//printf("recvfrom :%s\n",inet_ntoa(localaddr.sin_addr));
//printf("port :%d\n",ntohs(localaddr.sin_port));
d_ip = ntohl(localaddr.sin_addr.s_addr);
d_port = ntohs(localaddr.sin_port);
struct cmsghdr *cmsg ;
char dst[100],ipi[100];
for(cmsg = CMSG_FIRSTHDR(&mh);cmsg != NULL;cmsg = CMSG_NXTHDR ( &mh, cmsg ) )
{
struct in_pktinfo *pi = CMSG_DATA(cmsg);
if(cmsg->cmsg_level != IPPROTO_IP ||cmsg->cmsg_type != IP_PKTINFO )
{
continue;
}
if((inet_ntop(AF_INET,&(pi->ipi_spec_dst),dst,sizeof (dst))) !=NULL)
{
//printf("IPdst=%s\n",dst);
;
}
if((inet_ntop(AF_INET,&(pi->ipi_addr),ipi,sizeof(ipi))) !=NULL)
{
//printf("ipi_addr=%s\n",ipi);
;
}
}
reader->p_data[reader->f_count]->data_len = iRecvLen;
if (sock->root) {
reader->p_data[reader->f_count]->port = sock->port;
reader->p_data[reader->f_count]->ipaddr = sock->ipaddr;
}
else {
reader->p_data[reader->f_count]->port = d_port;
reader->p_data[reader->f_count]->ipi_port = sock->port;
reader->p_data[reader->f_count]->ipaddr = d_ip;
reader->p_data[reader->f_count]->ipi_addr = ntohl(inet_addr(ipi));
#if 0
printf("port :%d\n",reader->p_data[reader->f_count]->port);
printf("ipi_port :%d\n",reader->p_data[reader->f_count]->ipi_port);
printf("ipaddr :%d\n",reader->p_data[reader->f_count]->ipaddr);
printf("ipi_addr :%d\n",reader->p_data[reader->f_count]->ipi_addr);
localaddr.sin_addr.s_addr = reader->p_data[reader->f_count]->ipaddr;
printf("ipaddr :%s\n",inet_ntoa(localaddr.sin_addr));
localaddr.sin_addr.s_addr = reader->p_data[reader->f_count]->ipi_addr;
printf("ipiaddr :%s\n",inet_ntoa(localaddr.sin_addr));
printf("localaddr :%s\n",inet_ntoa(localaddr.sin_addr));
printf("port :%d\n",ntohs(localaddr.sin_port));
#endif
}
reader->f_count = (reader->f_count + 1) % (reader->depth);
if (reader->r_count == reader->f_count){
reader->r_count = (reader->r_count +1)% (reader->depth);
printf("leak+++++++\n");
}
}
#if 0
iRecvLen = recvfrom(fd, reader->p_data[reader->f_count]->data, BUF_LEN, 0, (struct sockaddr *)&tSocketClientAddr, &AddrLen);
if(iRecvLen > 0){
reader->p_data[reader->f_count]->data_len = iRecvLen;
if (sock->root) {
reader->p_data[reader->f_count]->port = sock->port;
reader->p_data[reader->f_count]->ipaddr = sock->ipaddr;
}
else {
reader->p_data[reader->f_count]->port = ntohs(tSocketClientAddr.sin_port);
reader->p_data[reader->f_count]->ipaddr = ntohl(tSocketClientAddr.sin_addr.s_addr);
}
reader->f_count = (reader->f_count + 1) % (reader->depth);
if (reader->r_count == reader->f_count){
reader->r_count = (reader->r_count +1)% (reader->depth);
printf("leak+++++++\n");
}
}
#endif
//printf("%s ,%d \n",__FUNCTION__,__LINE__);
return iRecvLen;
}
void eloop_sock_delete(struct eloop_sock *eloop_sock){
int i = 0;
if (eloop_sock->c_flag ==1 ) { /*±íÊŸ¿Í»§¶Ë*/
eloop_sock->root->cli_count --;
close(eloop_sock->sock_fd);
free(eloop_sock);
printf("client exit\n");
}
else {
if (eloop_sock->sock_fd) {
close (eloop_sock->sock_fd);
}
if (eloop_sock) {
if (eloop_sock->p_data) {
for(i = 0;i < eloop_sock->depth;i++){
if (eloop_sock->p_data[i]) {
free(eloop_sock->p_data[i]);
eloop_sock->p_data[i] = NULL;
}
}
free(eloop_sock->p_data);
eloop_sock->p_data = NULL;
}
pthread_mutex_destroy(&eloop_sock->r_mutex);
pthread_mutex_destroy(&eloop_sock->w_mutex);
pthread_cond_destroy(&eloop_sock->check_cond);
free(eloop_sock);
eloop_sock = NULL;
}
s_count --;
}
}
int cli_handle(struct eloop_sock *sock,pthread_t *pth_id)
{
int iRet;
struct eloop_sock *t_sock;
t_sock = (struct eloop_sock *)sock;
if (sock->root) { /*tcp*/
t_sock = sock->root;
}
else { /*udp*/
t_sock = sock;
}
pthread_mutex_lock(&t_sock->r_mutex);
iRet = RecvData(sock,sock->sock_fd);
if(sock->root && iRet < 0){
sock->active = 0;
}
pthread_mutex_unlock(&t_sock->r_mutex);
if (iRet > 0){
pthread_cond_signal(&t_sock->check_cond);
}
return 0;
}
int loc_srv_handle(struct eloop_sock *sock,pthread_t *pth_id)
{
struct eloop_sock *eloop_sock = NULL;
struct eloop_sock *eloop_client = NULL;
struct sockaddr_in tSocketClientAddr;
int c_fd = 0;
int rcv_size = 256*1024;
int AddrLen = 0;
int ret = 0;
eloop_sock = (struct eloop_sock *)sock;
AddrLen = sizeof(struct sockaddr);
memset(&tSocketClientAddr,0,sizeof(struct sockaddr_in));
c_fd = accept(eloop_sock->sock_fd, (struct sockaddr *)&tSocketClientAddr, &AddrLen);
if (-1 != c_fd)
{
eloop_client = (struct eloop_sock *)malloc(sizeof(struct eloop_sock));
if (eloop_client == NULL || eloop_sock->cli_count >= MAX_CLI_COUNT) {
close(c_fd);
return -1;
}
memset(eloop_client, 0, sizeof(struct eloop_sock));
eloop_client->sock_fd = c_fd;
eloop_client->active = 1;
eloop_client->handler = cli_handle;
eloop_client->s_fd = eloop_sock->sock_fd;
eloop_client->c_flag = 1;
eloop_client->root = eloop_sock;
eloop_client->port = ntohs(tSocketClientAddr.sin_port);
eloop_client->ipaddr = ntohl(tSocketClientAddr.sin_addr.s_addr);
setsockopt(c_fd, SOL_SOCKET, SO_RCVBUF, &rcv_size, sizeof(rcv_size));
ret = eloop_register_reader(eloop_client);
eloop_sock->cli_count++;
}
return (0);
}
void *eloop_thread(void *arg)
{
eloop_run();
return (void *)(0);
}
int tcp_init(u16 port,u32 depth){
int iRet = 0;
int opt = 1;
int i = 0;
int fd = 0;
int gdepth = 0;
int ret = -1;
struct eloop_sock *eloop_sock = NULL;
struct sockaddr_in ServerAddr;
struct in_addr ia;
struct eloop_sock *reader = NULL;
struct ip_mreq mreq;
if (eloop.init == 0) {
INIT_LIST_HEAD(&eloop.reader);
need_exit_flag = 0;
pthread_rwlock_init(&g_mutex, NULL);
iRet = pthread_create(&local_pth_id,NULL,eloop_thread,NULL);
//iRet = pthread_create(NULL,NULL,eloop_thread,NULL);
eloop.init = 1;
}
if(s_count >= MAX_SRV_COUNT){
ret = -1;
goto error;
}
if(depth == 0){
ret = -2;
goto error;
}
/*ÅжÏÊÇ·ñÒÑŸŽŽœš*/
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry(reader, &eloop.reader, list){
if (reader == NULL) {
break;
}
if(reader->c_flag == 0 && reader->socket_type == 0){
if(reader->port == port){
printf("already create tcp %s,%d\n",__FUNCTION__,__LINE__);
pthread_rwlock_unlock(&g_mutex);
return reader->sock_fd;
}
}
}
pthread_rwlock_unlock(&g_mutex);
gdepth = depth;
eloop_sock= (struct eloop_sock *)malloc(sizeof(struct eloop_sock));
if (eloop_sock == NULL) {
ret = -5;
goto error;
}
memset(eloop_sock, 0, sizeof(struct eloop_sock));
eloop_sock->port = port;
eloop_sock->p_data = (struct pakege **)malloc(sizeof(struct pakege *) * depth);
if (eloop_sock->p_data == NULL) {
ret = -5;
goto error;
}
memset(eloop_sock->p_data, 0, sizeof(struct pakege *) * depth);
for(i = 0;i < depth;i++){
eloop_sock->p_data[i] = (struct pakege *)malloc(sizeof(struct pakege));
if (eloop_sock->p_data[i] == NULL) {
ret = -5;
goto error;
}
memset(eloop_sock->p_data[i],0,sizeof(struct pakege));
}
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0){
ret = -3;
goto error;
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(port);
ServerAddr.sin_addr.s_addr = INADDR_ANY;
setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt));
memset(ServerAddr.sin_zero, 0, sizeof(ServerAddr.sin_zero));
iRet = bind(fd, (const struct sockaddr *)&ServerAddr, sizeof(struct sockaddr));
if (-1 == iRet){
ret = -4;
goto error;
}
eloop_sock->c_flag = 0;
eloop_sock->socket_type = 0;
eloop_sock->sock_fd = fd;
eloop_sock->depth = gdepth;
eloop_sock->handler = loc_srv_handle;
pthread_mutex_init(&eloop_sock->r_mutex, NULL);
pthread_mutex_init(&eloop_sock->w_mutex, NULL);
pthread_cond_init(&eloop_sock->check_cond, NULL);
eloop_register_reader(eloop_sock);
listen(eloop_sock->sock_fd, MAX_CLI_COUNT);
printf("creat tcp server success port %d %s,%d\n",port,__FUNCTION__,__LINE__);
s_count++;
return fd;
error:
if (fd) {
close (fd);
}
if (eloop_sock) {
if (eloop_sock->p_data) {
for(i = 0;i < depth;i++){
if (eloop_sock->p_data[i]) {
free(eloop_sock->p_data[i]);
eloop_sock->p_data[i] = NULL;
}
}
free(eloop_sock->p_data);
eloop_sock->p_data = NULL;
}
free(eloop_sock);
eloop_sock = NULL;
}
return ret;
}
int tcp_delete(int fd){
int i = 0;
struct eloop_sock *reader, *tmpr;
int found = 0;
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry_safe(reader, tmpr, &eloop.reader, list) {
if (reader->c_flag == 1 && reader->root->sock_fd == fd) {
reader->active = 0;
found = 1;
}
}
pthread_rwlock_unlock(&g_mutex);
if (found)
sleep(1);
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry_safe(reader, tmpr, &eloop.reader, list) {
if(reader->sock_fd == fd) {
break;
}
}
pthread_rwlock_unlock(&g_mutex);
if (reader) {
reader->active = 0;
sleep(1);
}
if (list_empty(&eloop.reader)) {
printf("delete all \n");
eloop.init = 0;
need_exit_flag = 1;
pthread_rwlock_destroy(&g_mutex);
}
return 0;
}
int tcp_rcv(int socket_fd,u8 *buff,u16 *port, u32 *ipaddr){
int ret = -1;
struct eloop_sock *reader, *tmpr;
if (buff == NULL || port== NULL || ipaddr== NULL) {
return -1;
}
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry_safe(reader, tmpr, &eloop.reader, list) {
if(reader->sock_fd == socket_fd) {
break;
}
}
pthread_rwlock_unlock(&g_mutex);
if (reader == NULL) {
return -1;
}
pthread_mutex_lock(&reader->r_mutex);
if (reader->r_count != reader->f_count) {
memcpy(buff, reader->p_data[reader->r_count]->data, reader->p_data[reader->r_count]->data_len);
*port = reader->p_data[reader->r_count]->port;
*ipaddr = reader->p_data[reader->r_count]->ipaddr;
ret = reader->p_data[reader->r_count]->data_len;
reader->r_count = (reader->r_count +1 ) % reader->depth;
}
else {
pthread_cond_wait(&reader->check_cond, &reader->r_mutex);
memcpy(buff, reader->p_data[reader->r_count]->data, reader->p_data[reader->r_count]->data_len);
*port = reader->p_data[reader->r_count]->port;
*ipaddr = reader->p_data[reader->r_count]->ipaddr;
ret = reader->p_data[reader->r_count]->data_len;
reader->r_count = (reader->r_count +1 ) % reader->depth;
}
pthread_mutex_unlock(&reader->r_mutex);
return ret;
}
int tcp_send( int fd, u8 *buff,u32 len,u16 port,u32 ipaddr){
int ret = -1;
struct eloop_sock *reader, *tmpr;
if (buff == NULL || len == 0) {
return -1;
}
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry_safe(reader, tmpr, &eloop.reader, list) {
if (reader->c_flag ==1 && reader->root->sock_fd == fd && reader->ipaddr == ipaddr && reader->port == port ){
break;
}
}
pthread_rwlock_unlock(&g_mutex);
if (reader == NULL) {
printf("cannot get read\n");
return -1;
}
pthread_mutex_lock(&reader->w_mutex);
struct sockaddr_in tSocketClientAddr;
tSocketClientAddr.sin_family = AF_INET;
tSocketClientAddr.sin_port = htons(port); /* host to net, short */
tSocketClientAddr.sin_addr.s_addr = htonl(ipaddr);
ret = sendto(reader->sock_fd, buff, len, 0,(struct sockaddr *)&tSocketClientAddr,sizeof(tSocketClientAddr));
pthread_mutex_unlock(&reader->w_mutex);
return ret;
}
int udp_init(u16 port,u32 ipaddr,u32 depth){
int iRet = 0;
int opt = 1;
int i = 0;
int fd = 0;
int gdepth = 0;
int ret = -1;
int rcv_size = 256*1024;
struct eloop_sock *eloop_sock = NULL;
struct sockaddr_in ServerAddr;
struct in_addr ia;
struct eloop_sock *reader = NULL;
struct ip_mreq mreq;
if (eloop.init == 0) {
INIT_LIST_HEAD(&eloop.reader);
need_exit_flag = 0;
pthread_rwlock_init(&g_mutex, NULL);
iRet = pthread_create(&local_pth_id,NULL,eloop_thread,NULL);
//iRet = pthread_create(NULL,NULL,eloop_thread,NULL);
eloop.init = 1;
}
if(s_count >= MAX_SRV_COUNT){
ret = -1;
goto error;
}
if(depth == 0){
ret = -2;
goto error;
}
if ((!(ipaddr >= 0xE0000001 && ipaddr <=0xEFFFFFFF)) && ipaddr != 0 ) {
ret = -2;
printf("0 ±íÊŸµ¥²¥£¬×é²¥ÇëÌîÐŽ×é²¥µØÖ·\n");
goto error;
}
/*ÅжÏÊÇ·ñÒÑŸŽŽœš*/
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry(reader, &eloop.reader, list){
if (reader == NULL) {
break;
}
if(reader->c_flag == 0 && reader->socket_type == 1){
if(reader->port == port){
printf("already create udp %s,%d\n",__FUNCTION__,__LINE__);
pthread_rwlock_unlock(&g_mutex);
return reader->sock_fd;
}
}
}
pthread_rwlock_unlock(&g_mutex);
gdepth = depth;
eloop_sock= (struct eloop_sock *)malloc(sizeof(struct eloop_sock));
if (eloop_sock == NULL) {
ret = -5;
goto error;
}
memset(eloop_sock, 0, sizeof(struct eloop_sock));
eloop_sock->port = port;
eloop_sock->p_data = (struct pakege **)malloc(sizeof(struct pakege *) * depth);
if (eloop_sock->p_data == NULL) {
ret = -5;
goto error;
}
memset(eloop_sock->p_data, 0, sizeof(struct pakege *) * depth);
for(i = 0;i < depth;i++){
eloop_sock->p_data[i] = (struct pakege *)malloc(sizeof(struct pakege));
if (eloop_sock->p_data[i] == NULL) {
ret = -5;
goto error;
}
memset(eloop_sock->p_data[i],0,sizeof(struct pakege));
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0){
ret = -3;
goto error;
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(port);
ServerAddr.sin_addr.s_addr = INADDR_ANY;
setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt));
setsockopt(fd,SOL_SOCKET,SO_RCVBUF, &rcv_size, sizeof(rcv_size));
setsockopt (fd,IPPROTO_IP,IP_PKTINFO,&opt,sizeof(opt));
if (ipaddr == 0) { /*unicast & broadcast*/
setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt));
}
else {/*muticast*/
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = htonl(ipaddr);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));
setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt));
}
memset(ServerAddr.sin_zero, 0, sizeof(ServerAddr.sin_zero));
iRet = bind(fd, (const struct sockaddr *)&ServerAddr, sizeof(struct sockaddr));
if (-1 == iRet){
ret = -4;
goto error;
}
eloop_sock->c_flag = 0;
eloop_sock->socket_type = 1;
eloop_sock->sock_fd = fd;
eloop_sock->depth = gdepth;
eloop_sock->handler = cli_handle;
pthread_mutex_init(&eloop_sock->r_mutex, NULL);
pthread_mutex_init(&eloop_sock->w_mutex, NULL);
pthread_cond_init(&eloop_sock->check_cond, NULL);
eloop_register_reader(eloop_sock);
printf("creat udp server success port %d %s,%d\n",port,__FUNCTION__,__LINE__);
s_count++;
return fd;
error:
if (fd) {
close (fd);
}
if (eloop_sock) {
if (eloop_sock->p_data) {
for(i = 0;i < depth;i++){
if (eloop_sock->p_data[i]) {
free(eloop_sock->p_data[i]);
eloop_sock->p_data[i] = NULL;
}
}
free(eloop_sock->p_data);
eloop_sock->p_data = NULL;
}
free(eloop_sock);
eloop_sock = NULL;
}
return ret;
}
int udp_delete(int fd){
int i = 0;
struct eloop_sock *reader, *tmpr;
int found = 0;
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry_safe(reader, tmpr, &eloop.reader, list) {
if(reader->socket_type == 1 && reader->sock_fd == fd) {
break;
}
}
pthread_rwlock_unlock(&g_mutex);
if (reader) {
reader->active = 0;
sleep(1);
}
if (list_empty(&eloop.reader)) {
printf("delete all \n");
eloop.init = 0;
need_exit_flag = 1;
pthread_rwlock_destroy(&g_mutex);
}
}
int udp_rcv(int socket_fd,u8 *buff,u16 *port, u32 *ipaddr){
return tcp_rcv(socket_fd, buff, port, ipaddr);
}
int udp_rcv_m(int socket_fd,u8 *buff,u16 *port, u32 *ipaddr,u16 *ipi_port,u32 *ipi_addr){
int ret = -1;
struct eloop_sock *reader, *tmpr;
if (buff == NULL || port== NULL || ipaddr== NULL) {
return -1;
}
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry_safe(reader, tmpr, &eloop.reader, list) {
if(reader->sock_fd == socket_fd) {
break;
}
}
pthread_rwlock_unlock(&g_mutex);
if (reader == NULL) {
return -1;
}
pthread_mutex_lock(&reader->r_mutex);
if (reader->r_count != reader->f_count) {
memcpy(buff, reader->p_data[reader->r_count]->data, reader->p_data[reader->r_count]->data_len);
*port = reader->p_data[reader->r_count]->port;
*ipaddr = reader->p_data[reader->r_count]->ipaddr;
*ipi_port = reader->p_data[reader->r_count]->ipi_port;
*ipi_addr = reader->p_data[reader->r_count]->ipi_addr;
ret = reader->p_data[reader->r_count]->data_len;
reader->r_count = (reader->r_count +1 ) % reader->depth;
}
else {
pthread_cond_wait(&reader->check_cond, &reader->r_mutex);
memcpy(buff, reader->p_data[reader->r_count]->data, reader->p_data[reader->r_count]->data_len);
*port = reader->p_data[reader->r_count]->port;
*ipaddr = reader->p_data[reader->r_count]->ipaddr;
*ipi_port = reader->p_data[reader->r_count]->ipi_port;
*ipi_addr = reader->p_data[reader->r_count]->ipi_addr;
ret = reader->p_data[reader->r_count]->data_len;
reader->r_count = (reader->r_count +1 ) % reader->depth;
}
pthread_mutex_unlock(&reader->r_mutex);
return ret;
}
int udp_send( int fd, u8 *buff,u32 len,u16 port,u32 ipaddr){
int ret = -1;
struct eloop_sock *reader, *tmpr;
if (buff == NULL || len ==0 || len > BUF_LEN) {
return -1;
}
pthread_rwlock_rdlock(&g_mutex);
list_for_each_entry_safe(reader, tmpr, &eloop.reader, list) {
if (reader->sock_fd ==fd){
break;
}
}
pthread_rwlock_unlock(&g_mutex);
if (reader == NULL) {
printf("cannot get read\n");
return -1;
}
pthread_mutex_lock(&reader->w_mutex);
struct sockaddr_in tSocketClientAddr;
tSocketClientAddr.sin_family = AF_INET;
tSocketClientAddr.sin_port = htons(port); /* host to net, short */
tSocketClientAddr.sin_addr.s_addr = htonl(ipaddr);
ret = sendto(reader->sock_fd, buff, len, 0,(struct sockaddr *)&tSocketClientAddr,sizeof(tSocketClientAddr));
pthread_mutex_unlock(&reader->w_mutex);
return ret;
}
#if 0
int main(int argc, char **argv)
{
/*
int iSocketClient = tcp_init(8888,10);
unsigned char ucSendBuf[4096];
unsigned short port;
unsigned int ip;
int iRet;
if ( iSocketClient < 0){
printf("socket_init error!\n");
return -1;
}
//signal(SIGINT,ctrl_c_handler);
while(!g_run) {
iRet = tcp_rcv(iSocketClient, ucSendBuf,&port, &ip);
if (iRet) {
iRet = tcp_send(iSocketClient, ucSendBuf,iRet, port, ip);
}
printf("iRet=%d\n",iRet);
}
tcp_delete(iSocketClient);
*/
unsigned char ucSendBuf[4096];
unsigned short port;
unsigned int ip;
int iRet;
int iSocketClient = udp_init(8888,0,10);
int muticastip = htonl(inet_addr("224.0.1.10"));
iSocketClient = udp_init(55558, muticastip, 1024);
if (iSocketClient < 0) {
printf("can not init udp muticast \n");
}
while(!g_run) {
iRet = udp_rcv(iSocketClient, ucSendBuf,&port, &ip);
printf("recv iRet=%d\n",iRet);
if (iRet > 0) {
iRet = udp_send(iSocketClient, ucSendBuf,iRet, port, ip);
}
printf("iRet=%d\n",iRet);
}
tcp_delete(iSocketClient);
return 0;
}
#endif