这次主要是想上传一下代码,写了一个负载均衡器。
//客户端代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<sys/un.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<error.h>
#include<string.h>
const int BUFF_SIZE = 128;
const char *ip = "127.0.0.1";
int conn(int port)
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
assert(sockfd>0);
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
inet_pton(AF_INET,ip,&saddr.sin_addr);
saddr.sin_port = htons(port);
int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res<0)
{
close(sockfd);
return -1;
}
return sockfd;
}
int main(int argc,char *argv[])
{
int load_sockfd = conn(6500);
if(load_sockfd<0)
{
printf("connect load error\n");
return 1;
}
else
{
printf("connect load succese\n");
}
char buf[5];
memset(buf,0,5);
int n = recv(load_sockfd,buf,5,0);
if(n <= 0)
{
printf("load close\n");
close(load_sockfd);
return 1;
}
int port = atoi(buf);
printf("port = %d\n",port);
n = send(load_sockfd,"ok",2,0);
if(n<0)
{
printf("load close\n");
close(load_sockfd);
return 1;
}
close(load_sockfd);
int sockfd = conn(port);
if(sockfd<0)
{
printf("connect server(%d) error\n",port);
return 1;
}
while(1)
{
char buff[BUFF_SIZE];
memset(buff,0,BUFF_SIZE);
printf("input\n");
fgets(buff,127,stdin);
int n = send(sockfd,buff,BUFF_SIZE-1,0);
if(n<0)
{
printf("send error\n");
break;
}
memset(buff,0,127);
n = recv(sockfd,buff,2,0);
if(n <= 0)
{
printf("recv error\n");
break;
}
printf("recv = %s\n",buff);
}
close(sockfd);
return 0;
}
均衡器代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<sys/un.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/epoll.h>
#include<string.h>
#include<fcntl.h>
#include<errno.h>
const int BUFF_SIZE = 128;
const int MAX_EVENT_NUMBLE = 100;
const int SERVER_NUMBLE = 5;
const char *ip = "127.0.0.1";
pthread_mutex_t mutex;
typedef struct Node
{
int count;
char port[5];
}NODE;
NODE server_data[5] =
{
{0,"6600"},
{0,"6700"},
{0,"6800"},
{0,"6900"},
{0,"7000"},
};
int min_server_data()
{
int i = 1;
int j = 0;
for(; i<5; ++i)
{
if( server_data[i].count < server_data[j].count)
{
j = i;
}
}
++server_data[j].count;
printf("count port\n");
for(i = 0; i<5; ++i)
{
printf("%d %s\n",server_data[i].count,server_data[i].port);
}
return j;
}
void *worker(void *arg)
{
int cli_sockfd = *(int*)arg;
printf("pthread running cli_sockfd(%d)\n",cli_sockfd);
pthread_mutex_lock(&mutex);
int i = min_server_data();
pthread_mutex_unlock(&mutex);
char buff[5];
memset(buff,0,5);
strcpy(buff,server_data[i].port);
int n = send(cli_sockfd,buff,5,0);
if(n < 0)
{
close(cli_sockfd);
printf("send cli(%d) error\n",cli_sockfd);
return NULL;
}
memset(buff,0,5);
n = recv(cli_sockfd,buff,2,0);
if(n<0)
{
close(cli_sockfd);
printf("recv cli(%d) error\n",cli_sockfd);
return NULL;
}
printf("buff = %s\n",buff);
close(cli_sockfd);
}
int main(int argc,char *argv[])
{
if(argc<2)
{
printf("argc<2\n");
return 1;
}
pthread_mutex_init(&mutex,NULL);
int port = atoi(argv[1]);
int listenfd = socket(AF_INET,SOCK_STREAM,0);
assert(listenfd>=0);
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
inet_pton(AF_INET,ip,&saddr.sin_addr);
saddr.sin_port = htons(port);
int res = bind(listenfd,(struct sockaddr*)&saddr,sizeof(saddr));
assert(res != -1);
res = listen(listenfd,5);
assert(res != -1);
while(1)
{
struct sockaddr_in caddr;
socklen_t caddr_len = sizeof(caddr);
int connfd = accept(listenfd,(struct sockaddr*)&caddr,&caddr_len);
assert(connfd>0);
printf("cli(%d) connect\n",connfd);
pthread_t thread;
pthread_create(&thread,NULL,&worker,&connfd);
}
close(listenfd);
pthread_mutex_destroy(&mutex);
return 0;
}
服务器代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<sys/un.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/epoll.h>
#include<string.h>
#include<fcntl.h>
#include<errno.h>
const int BUFF_SIZE = 128;
const int MAX_EVENT_NUMBLE = 100;
const char *ser_ip = "127.0.0.1";
typedef struct fds
{
int epollfd;
int sockfd;
}fds;
/*将文件描述符设置为非阻塞的*/
int setnonblocking(int fd)
{
int old_option = fcntl(fd,F_GETFL);
int new_option = old_option |O_NONBLOCK;
fcntl(fd,F_SETFL,new_option);
return old_option;
}
/*将文件描述符fd的EPOLLIN事件注册到内核事件表中,参数enable_et指定是否对FD
采用EPOLLONESHUT事件*/
void Addfd(int epollfd,int fd,int enable_et)
{
struct epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN | EPOLLET;
if(enable_et)
{
event.events |= EPOLLONESHOT;
}
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);
setnonblocking(fd);
}
/*重置FD上的事件,这样操作以后,尽管fd上的EPOLLONESHOT事件被注册,但是操作系统仍然会触发FD上的EPOLLIN事件,且只触发一次*/
void reset_oneshot(int epollfd,int fd)
{
struct epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&event);
}
void *worker(void *arg)
{
int cli_sockfd = ((fds*)arg)->sockfd;
int epollfd = ((fds*)arg)->epollfd;
printf("pthread running cli_sockfd(%d)\n",cli_sockfd);
while(1)
{
char buff[BUFF_SIZE];
memset(buff,0,BUFF_SIZE);
int n = recv(cli_sockfd,buff,BUFF_SIZE-1,0);
if(n == 0)
{
printf("cli(%d)closed the connection\n",cli_sockfd);
close(cli_sockfd);
break;
}
else if(n<0)
{
if(errno == EAGAIN)
{
reset_oneshot(epollfd,cli_sockfd);
printf("read later\n");
break;
}
close(cli_sockfd);
break;
}
else
{
printf("recv cli(%d) : %s\n",cli_sockfd,buff);
n = send(cli_sockfd,"ok",2,0);
if(n<0)
{
printf("cli(%d) close\n");
close(cli_sockfd);
break;
}
memset(buff,0,BUFF_SIZE);
}
}
}
int main(int argc,char *argv[])
{
if(argc<2)
{
printf("argc<2\n");
return 1;
}
int port = atoi(argv[1]);
int listenfd = socket(AF_INET,SOCK_STREAM,0);
assert(listenfd>=0);
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
inet_pton(AF_INET,ser_ip,&saddr.sin_addr);
saddr.sin_port = htons(port);
int res = bind(listenfd,(struct sockaddr*)&saddr,sizeof(saddr));
assert(res != -1);
res = listen(listenfd,5);
assert(res != -1);
struct epoll_event events[MAX_EVENT_NUMBLE];
int epollfd = epoll_create(5);
assert(epollfd != -1);
Addfd(epollfd,listenfd,0);
while(1)
{
int ret = epoll_wait(epollfd,events,MAX_EVENT_NUMBLE,-1);
printf("ret = %d\n",ret);
int i = 0;
for(; i<ret; ++i)
{
int sockfd = events[i].data.fd;
if(sockfd == listenfd)
{
struct sockaddr_in caddr;
socklen_t caddr_len = sizeof(caddr);
int connfd = accept(listenfd,(struct sockaddr*)&caddr,&caddr_len);
assert(connfd>0);
printf("load(%d) connect\n",connfd);
Addfd(epollfd,connfd,1);
}
else if(events[i].events & EPOLLIN)
{
pthread_t thread;
fds fds_work;
fds_work.epollfd = epollfd;
fds_work.sockfd = sockfd;
pthread_create(&thread,NULL,&worker,&fds_work);
}
}
}
close(listenfd);
return 0;
}
569

被折叠的 条评论
为什么被折叠?



