Linux负载均衡器

来源:互联网 发布:怎么学软件 编辑:程序博客网 时间:2024/06/15 03:33

    这次主要是想上传一下代码,写了一个负载均衡器。

//客户端代码:

#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;}




原创粉丝点击