服务端
static int failover_read_from_tcp(int fd, char * buf, int size)
{
int offset = 0;
int bytes;
int wanted = size;
while (wanted > 0) {
bytes = read(fd, buf+offset, wanted);
if (bytes <= 0) {
return -1;
}
wanted -= bytes;
offset += bytes;
}
return 0;
}
static void *thread_listen(void *arg)
{
int i = 0;
int sockfd = -1; //server
int epfd = -1; //epoll
int fd = -1; //client
int num = 0;
struct sockaddr_in local_addr;
struct sockaddr_in remote_address;
int len = sizeof(remote_address);
struct epoll_event ev;
struct epoll_event events[10];
struct failover_request request;
char *recvBuf;
ms_task_set_name(THREAD_NAME_FAILOVER_LISTEN);
if (global_failover_conf.task_listen_run)
{
request.buf= ms_malloc(MAX_DATA_SIZE);
if (request.buf == NULL)
{
msdebug(DEBUG_WRN, "thread listen malloc failed");
ms_task_quit(NULL);
return 0;
}
recvBuf = request.buf;
sockfd =socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
msdebug(DEBUG_WRN, "thread listen socket creat failed");
ms_free(request.buf);
ms_task_quit(NULL);
return 0;
}
epfd = epoll_create(250);
ev.data.fd = sockfd;
ev.events = EPOLLIN; //read
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
memset(&local_addr,0,sizeof(local_addr));
local_addr.sin_family=AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port=htons(8000);
if (bind(sockfd, (struct sockaddr *) &local_addr, sizeof(local_addr)) == -1)
{
msdebug(DEBUG_WRN, "thread socket bind failed!");
ms_free(request.buf);
close(sockfd);
ms_task_quit(NULL);
return 0;
}
if (listen(sockfd, 50) == -1)
{
msdebug(DEBUG_WRN, "thread socket listen failed!");
ms_free(request.buf);
close(sockfd);
ms_task_quit(NULL);
return 0;
}
while (global_failover_conf.task_listen_run)
{
num = epoll_wait(epfd, events, 50, 500);
if(num < 1) continue;
msprintf("###### num:%d sockfd:%d ######\n", num, sockfd);
for (i = 0; i < num; i++)
{
memset(request.buf, 0x0, SOCKET_DATA_MAX_SIZE);
if (sockfd == events[i].data.fd && (events[i].events & EPOLLIN))
{
fd = accept(sockfd, (struct sockaddr *)&remote_address, (socklen_t *)&len);
inet_ntop(AF_INET, (void*)&(remote_address.sin_addr), request.ipaddr, sizeof(request.ipaddr));
msprintf("###### fd:%d ip:%s #######\n", fd, request.ipaddr);
if (failover_read_from_tcp(fd, (char*)&request.header, sizeof(struct failover_header)) == 0)
{
if(request.header.size > MAX_DATA_SIZE || request.header.condition != FAILOVER_CONDITION_CODE)
{
msprintf("##### unkonw connect ######\n");
}
if(request.header.size > 0)
{
if (failover_read_from_tcp(fd, recvBuf, request.header.size) < 0)
{
msprintf("##### read buf failed! #####\n");
}
if(request.header.size < SOCKET_DATA_MAX_SIZE)
recvBuf[request.header.size] = '\0';
msprintf("###### recv 111 buf :%s ########\n", recvBuf);
}
}
ev.data.fd = fd;
ev.events = EPOLLIN;
epoll_ctl(epfd,EPOLL_CTL_ADD,ev.data.fd,&ev);
}
else if (events[i].events & EPOLLIN)
{
msprintf("###### old fd:%d ######\n", events[i].data.fd);
if (events[i].data.fd < 0) continue;
if (failover_read_from_tcp(fd, recvBuf, request.header.size) < 0)
{
//disconnect
msprintf("##### dis connect 000 ######\n");
ev.data.fd = events[i].data.fd;
ev.events = EPOLLIN; //read
epoll_ctl(epfd, EPOLL_CTL_DEL, ev.data.fd, &ev);
close(events[i].data.fd);
events[i].data.fd = -1;
continue;
}
msprintf("##### size:%d #####\n", request.header.size);
if(request.header.size > MAX_DATA_SIZE || request.header.condition != FAILOVER_CONDITION_CODE)
{
msprintf("##### unkonw connect ######\n");
ev.data.fd = events[i].data.fd;
ev.events = EPOLLIN; //read
epoll_ctl(epfd, EPOLL_CTL_DEL, ev.data.fd, &ev);
close(events[i].data.fd);
events[i].data.fd = -1;
continue;
}
if(request.header.size > 0)
{
if (failover_read_from_tcp(fd, recvBuf, request.header.size) < 0)
{
msprintf("##### dis connect 111 ######\n");
ev.data.fd = events[i].data.fd;
ev.events = EPOLLIN; //read
epoll_ctl(epfd, EPOLL_CTL_DEL, ev.data.fd, &ev);
close(events[i].data.fd);
events[i].data.fd = -1;
}
else
{
if(request.header.size < SOCKET_DATA_MAX_SIZE)
{
recvBuf[request.header.size] = '\0';
}
msprintf("###### recv 222 buf:%s ########\n", recvBuf);
}
}
}
else
{
msprintf("### else fd:%d %d ####\n", events[i].data.fd, events[i].events);
}
}
}
ms_free(request.buf);
close(sockfd);
}
ms_task_quit(NULL);
return 0;
}
客户端
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define MAXLINE 1024
#define MAX_DATA_SIZE (1*1024*1024)//1M
#define FAILOVER_CONDITION_CODE 0x20120610
struct failover_header{
int condition;
int type;
int from;
int req;
int size;
int crc;
};
struct failover_packet{
struct failover_header header;
char buf[MAX_DATA_SIZE];
};
int main(int argc,char **argv)
{
char *servInetAddr = "192.168.2.143";
int socketfd;
struct sockaddr_in sockaddr;
char recvline[MAXLINE], sendline[MAXLINE];
int n;
char *sendBuf = NULL;
sendBuf = malloc(MAX_DATA_SIZE+sizeof(struct failover_header));
struct failover_header *header;
if(argc != 2)
{
printf("client <ipaddress> \n");
//exit(0);
}
socketfd = socket(AF_INET,SOCK_STREAM,0);
memset(&sockaddr,0,sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(8000);
inet_pton(AF_INET,servInetAddr,&sockaddr.sin_addr);
if((connect(socketfd,(struct sockaddr*)&sockaddr,sizeof(sockaddr))) < 0 )
{
printf("connect error %s errno: %d\n",strerror(errno),errno);
exit(0);
}
printf("send message to server\n");
//fgets(sendline,1024,stdin);
snprintf(sendline, sizeof(sendline), "%s", "abc");
header = (struct failover_header *)sendBuf;
header->condition = FAILOVER_CONDITION_CODE;
header->type = 1;
header->from = 2;
header->req = 3;
header->size = strlen(sendline);
header->crc = 0;
memcpy(sendBuf+sizeof(struct failover_header), sendline, strlen(sendline));
printf(" send len:%d %d \n", sizeof(struct failover_header),header->size);
if((send(socketfd,sendBuf,header->size+sizeof(struct failover_header),0)) < 0)
{
printf("send mes error: %s errno : %d",strerror(errno),errno);
exit(0);
}
sleep(1);
#if 1
snprintf(sendline, sizeof(sendline), "%s", "efg");
memcpy(sendBuf+sizeof(struct failover_header), sendline, 3);
//*(sendBuf+sizeof(struct failover_header)+3) = '\0';
printf("###### 111 %s ######\n", sendBuf+sizeof(struct failover_header));
header->size = 3;
if((send(socketfd,sendBuf,header->size+sizeof(struct failover_header),0)) < 0)
{
printf("send mes error: %s errno : %d",strerror(errno),errno);
exit(0);
}
#endif
free(sendBuf);
close(socketfd);
printf("exit\n");
exit(0);
}