tcp udp多連接,可以創建多個服務器,單播、廣播、組播

思路如下: 

部分結構體定義如下:

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章