#define RELAY_IP "0.0.0.0"
#define RELAY_PORT "502"
struct RelayDeviceInfo
{
unsigned int addr;
short port;
int sockfd;
int useflag;
};
int relay_listen_sock = 0;
struct RelayDeviceInfo relaydevice[MAX_RELAY_STATION_NUM];
int relay_create_socket(void)
{
struct addrinfo hint, *addr;
int opt = 1;
int ret = 0;
relay_listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (relay_listen_sock < 0)
{
DBG(DBG_CRITICAL, "Create relay socket fails:%s", strerror(errno));
return VOIP_FAIL;
}
memset(&addr, 0, sizeof(addr));
hint.ai_flags = 0;
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
ret = setsockopt(relay_listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (ret==-1) {
DBG(DBG_ERROR, "setsockopt socket fails:%s", strerror(errno));
return VOIP_FAIL;
}
ret = getaddrinfo(RELAY_IP, RELAY_PORT, &hint, &addr);
if (ret!=0) {
fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ret));
exit(1);
}
if (bind(relay_listen_sock, addr->ai_addr, addr->ai_addrlen) == -1)
{
DBG(DBG_CRITICAL, "Bind relay socket fails:%s", strerror(errno));
close(relay_listen_sock);
return VOIP_FAIL;
}
freeaddrinfo(addr);
ret = listen(relay_listen_sock, 255);
if (ret==-1) {
DBG(DBG_ERROR, "listen socket fails:%s", strerror(errno));
return VOIP_FAIL;
}
return VOIP_OK;
}
void relay_accept_connect()
{
struct sockaddr_in peer;
socklen_t peer_len;
int relay_sock;
int i = 0;
peer_len = sizeof(peer);
relay_sock = accept(relay_listen_sock, (struct sockaddr*)&peer, &peer_len);
if (relay_sock==-1) {
DBG(DBG_ERROR, "accept socket fails:%s", strerror(errno));
return VOIP_FAIL;
}
fcntl(relay_sock, F_SETFL, O_NONBLOCK);
DBG(DBG_CRITICAL,"Accept relay connect, addr:%s, port:%d",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
//add relay socket connection
for (i = 0 ; i < MAX_RELAY_STATION_NUM; i++)
{
if (relaydevice[i].useflag && relaydevice[i].addr == ntohl(peer.sin_addr.s_addr))
{
if (relaydevice[i].sockfd > 0)
{
close(relaydevice[i].sockfd);
}
relaydevice[i].sockfd = relay_sock;
relaydevice[i].addr = ntohl(peer.sin_addr.s_addr);
relaydevice[i].port = ntohs(peer.sin_port);
break;
}
}
if (i == MAX_RELAY_STATION_NUM)
{
for (i = 0; i < MAX_RELAY_STATION_NUM; i++)
{
if (!relaydevice[i].useflag)
{
relaydevice[i].useflag = 1;
relaydevice[i].sockfd = relay_sock;
relaydevice[i].addr = ntohl(peer.sin_addr.s_addr);;
relaydevice[i].port = ntohs(peer.sin_port);
break;
}
}
}
if (i == MAX_RELAY_STATION_NUM)
{
DBG(DBG_ERROR, "accept sockfd overflow");
}
}
void Relay_process_msg_thread()
{
unsigned char read_buf[MAX_DATA_LENGTH_RELAY_INTF+1] = {'\0'};
struct timeval next_interval;
fd_set fd_read;
int nfds;
int ret;
int peer_addr;
short peer_port;
struct timeval curr_time;
struct timezone time_zone;
int i = 0;
memset(&relaydevice,0,sizeof(struct RelayDeviceInfo)*MAX_RELAY_STATION_NUM);
relay_create_socket();
while(1)
{
gettimeofday(&curr_time,&time_zone);
FD_ZERO(&fd_read);
nfds = 0;
FD_SET(relay_listen_sock, &fd_read);
if(relay_listen_sock > nfds)
{
nfds = relay_listen_sock;
}
for (i = 0; i < MAX_RELAY_STATION_NUM; i++)
{
if(relaydevice[i].useflag && relaydevice[i].sockfd > 0)
{
FD_SET(relaydevice[i].sockfd, &fd_read);
if(relaydevice[i].sockfd > nfds)
{
nfds = relaydevice[i].sockfd;
}
}
}
next_interval.tv_sec = 0;
next_interval.tv_usec = 100000; //100ms
ret = select(nfds+1, &fd_read, NULL, NULL, &next_interval);
if (ret < 0)
{
continue;
}
if(FD_ISSET(relay_listen_sock, &fd_read))
{
relay_accept_connect();
}
for (i = 0; i < MAX_RELAY_STATION_NUM; i++)
{
if(FD_ISSET(relaydevice[i].sockfd, &fd_read))
{
memset(read_buf, 0, MAX_DATA_LENGTH_RELAY_INTF);
ret = Relay_Receive_Packet(relaydevice[i].sockfd,read_buf,MAX_DATA_LENGTH_RELAY_INTF,&peer_addr,&peer_port);
if (ret > 0)
{
CheakRelayData(relaydevice[i].addr,read_buf,ret);
}
else
{
close(relaydevice[i].sockfd);
memset(&relaydevice[i],0,sizeof(relaydevice[i]));
}
}
}
}
}
socket select
最新推荐文章于 2016-11-10 09:20:09 发布