linux网络编程-多client多server一个watcher

2021/12/4 7:16:37

本文主要是介绍linux网络编程-多client多server一个watcher,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

client.cpp-->client

server.cpp-->server

watcher.cpp+server.h-->watcher

client.cpp

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>

//从watcher获取可用的服务端
int connect_watcher(std::string& ip,unsigned short int& port)
{
    int sockfd;
    sockaddr_in watcher_addr;
    
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        printf("客户端创建sockfd失败\n");
        return -1;
    }
    memset(&watcher_addr,0,sizeof(sockaddr_in));
    watcher_addr.sin_family=AF_INET;
    watcher_addr.sin_port=htons(11112);
    watcher_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //connect
    if(connect(sockfd,(sockaddr*)(&watcher_addr),sizeof(sockaddr))==-1)
    {
        printf("failed to connect to server\n");
        return -1;
    }
    char buffer[1024];
    int nbytes=read(sockfd,buffer,1023);
    if(nbytes>0)
    {
        printf("接收到watcher端%d个字节:\n",nbytes);
        buffer[nbytes]='\0';
        printf("%s\n",buffer);
        std::string server_info(buffer);
        //解析ip和port
        int pos=server_info.find(":");
        std::string ipstr=server_info.substr(0,pos);
        std::string portstr=server_info.substr(pos+1,server_info.size()-pos);
        if(ipstr.empty()||portstr.empty())
        {
            printf("failed to accquire server ip and port\n");
            return -1;
        }
        else
        {
            ip=ipstr;
            port=std::stoi(portstr);
            return 0;
        }

    }
    return -1;    
}

int main()
{
    //连接到watcher
    std::string server_ip;
    unsigned short int server_port;
    if(connect_watcher(server_ip,server_port)<0)
    {
        printf("failed to contact to wather...\n");
        return -1;
    }

    int sockfd;
    sockaddr_in server_addr;
    
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        printf("客户端创建sockfd失败\n");
        return -1;
    }
    memset(&server_addr,0,sizeof(sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_port=htons(server_port);
    server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str());

    //connect
    if(connect(sockfd,(sockaddr*)(&server_addr),sizeof(sockaddr))==-1)
    {
        printf("failed to connect to server\n");
        return -1;
    }

    char buffer[1024];
    while(true)
    {
        int nbytes=read(sockfd,buffer,1023);
        if(nbytes>0)
        {
            printf("接收到服务端%d个字节:\n",nbytes);
            buffer[nbytes]='\0';
            printf("%s\n",buffer);
        }
    }

    //close
    close(sockfd);
    return 0;
}

server.cpp

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>

int connect_watcher(unsigned short int port)
{
    int sockfd;
    sockaddr_in watcher_addr;
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        printf("服务端创建sockfd失败\n");
        return -1;
    }
    memset(&watcher_addr,0,sizeof(sockaddr_in));
    watcher_addr.sin_family=AF_INET;
    watcher_addr.sin_port=htons(11111);
    watcher_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //connect to watcher
    if(connect(sockfd,(sockaddr*)(&watcher_addr),sizeof(sockaddr))==-1)
    {
        printf("failed to connect to watcher\n");
        return -1;
    }
    //把自己正在监听的端口发送给watcher端
    std::string msg="port="+std::to_string(port);
    int nbytes=msg.size();
    printf("即将发送%d个字节\n",nbytes);
    int nw=write(sockfd,msg.c_str(),nbytes);
    if(nw!=nbytes)
    {
        printf("写入socket失败\n");
        return -1;
    }
    //从watcher端读取信息
    char buffer[1024];
    int nb=read(sockfd,buffer,1023);
    if(nb>0)
    {
        printf("接收到watcher端%d个字节:\n",nb);
        buffer[nb]='\0';
        printf("%s\n",buffer);
    }
    return 0;
}

int main(int argc,char* argv[])
{
    if(argc<2)
    {
        printf("no port set!\n");
        return -1;
    }
    unsigned short int port=std::stoi(std::string(argv[1]));
    if(connect_watcher(port)<0)
    {
        printf("failed to contact to watcher...\n");
        return -1;
    }

    //当与watcher成功建立联系后,才会成为server
    int sockfd;
    sockaddr_in server_addr;
    sockaddr_in client_addr;

    //创建socket
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        printf("server failed to create the socket\n");
        return -1;
    }
    memset(&server_addr,0,sizeof(sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    server_addr.sin_port=htons(port);

    //bind
    if(bind(sockfd,(sockaddr*)(&server_addr),sizeof(sockaddr))==-1)
    {
        printf("server failed to bind the socket\n");
        fprintf(stderr,"Socket error:%s\n",strerror(errno));
        return -1;
    }
    //listen
    if(listen(sockfd,5)==-1)
    {
        printf("server failed to listen the socket\n");
        return -1;
    }

    int sockfd_accepted;
    socklen_t sin_size=sizeof(sockaddr_in);
    while(true)
    {
        sockfd_accepted=accept(sockfd,(sockaddr*)(&client_addr),&sin_size);
        if(sockfd_accepted==-1)
        {
            printf("server accept sockfd error\n");

        }
        else
        {
            printf("server get a client connection from %d\n",client_addr.sin_port);
            //其他的处理过程
            char buffer[1024]="xxxxxxxxx";
            int nbytes=strlen(buffer);
            printf("即将发送%d个字节\n",nbytes);
            int nw=write(sockfd_accepted,buffer,nbytes);
            if(nw!=nbytes)
            {
                printf("写入socket失败\n");
            }
        }
    }
    close(sockfd);

    //
    printf("server will be closed!\n");
    return 0;
}

watcher.cpp

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#include <string>
#include <vector>

#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <pthread.h>

#include "server.h"
//监视所有可用的开启的服务端,
std::vector<Server> Servers_on_line;
int get_server_info(std::string& ip,unsigned short int& port);
void* server_proc(void*);
void* client_proc(void*);

int main()
{
    //开启监听服务端的工作
    pthread_t t1;
    pthread_create(&t1,NULL,&server_proc,NULL);
    
    pthread_t t2;
    pthread_create(&t2,NULL,&client_proc,NULL);

    pthread_join(t1,NULL);
    pthread_join(t2,NULL);    
    
    //
    printf("say goodby...\n");
    return 0;
}
//用于处理client连接的线程
void* client_proc(void*)
{
    unsigned short int port=11112;
    int sockfd;
    sockaddr_in watcher_addr;
    sockaddr_in client_addr;

    //创建socket
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        printf("watcher failed to create the socket\n");
        return (void*)-1;
    }
    memset(&watcher_addr,0,sizeof(sockaddr_in));
    watcher_addr.sin_family=AF_INET;
    watcher_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    watcher_addr.sin_port=htons(port);

    //bind
    if(bind(sockfd,(sockaddr*)(&watcher_addr),sizeof(sockaddr))==-1)
    {
        printf("watcher failed to bind the socket\n");
        fprintf(stderr,"Socket error:%s\n",strerror(errno));
        return (void*)-1;
    }
    //listen
    if(listen(sockfd,5)==-1)
    {
        printf("watcher failed to listen the socket\n");
        return (void*)-1;
    }

    int sockfd_accepted;
    socklen_t sin_size=sizeof(sockaddr_in);
    while(true)
    {
        sockfd_accepted=accept(sockfd,(sockaddr*)(&client_addr),&sin_size);
        if(sockfd_accepted==-1)
        {
            printf("watcher accept sockfd error\n");
        }
        else
        {
            printf("watcher get a client connection from %d\n",client_addr.sin_port);
            //其他的处理过程
            std::string server_ip;
            unsigned short int server_port;
            get_server_info(server_ip,server_port);
                        
            //将获取到的服务器地址发送给客户端
            std::string msg=server_ip+":"+std::to_string(server_port);
            int nbytes=msg.size();
            printf("即将发送%d个字节\n",nbytes);
            int nw=write(sockfd_accepted,msg.c_str(),nbytes);
            if(nw!=nbytes)
            {
                printf("写入socket失败\n");
            }
        }
    }
    close(sockfd);

    //
    printf("watcher will be closed!\n");
    return 0;
}

//用于处理server连接和记录的线程
void* server_proc(void*)
{
    unsigned short int port=11111;
    int sockfd;
    sockaddr_in watcher_addr;
    sockaddr_in server_addr;

    //创建socket
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        printf("watcher failed to create the socket\n");
        return (void*)-1;
    }
    memset(&watcher_addr,0,sizeof(sockaddr_in));
    watcher_addr.sin_family=AF_INET;
    watcher_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    watcher_addr.sin_port=htons(port);

    //bind
    if(bind(sockfd,(sockaddr*)(&watcher_addr),sizeof(sockaddr))==-1)
    {
        printf("watcher failed to bind the socket\n");
        fprintf(stderr,"Socket error:%s\n",strerror(errno));
        return (void*)-1;
    }
    //listen
    if(listen(sockfd,5)==-1)
    {
        printf("watcher failed to listen the socket\n");
        return (void*)-1;
    }

    int sockfd_accepted;
    socklen_t sin_size=sizeof(sockaddr_in);
    while(true)
    {
        sockfd_accepted=accept(sockfd,(sockaddr*)(&server_addr),&sin_size);
        if(sockfd_accepted==-1)
        {
            printf("watcher accept sockfd error\n");
        }
        else
        {
            printf("watcher get a server connection from %d\n",server_addr.sin_port);
            //其他的处理过程
            std::string server_ip;
            unsigned short int server_port;

            //接收服务端发来的监听端口信息
            char buffer[1024];
            int nbytes=read(sockfd_accepted,buffer,1023);
            if(nbytes>0)
            {
                printf("接收到服务端%d个字节:\n",nbytes);
                buffer[nbytes]='\0';
                printf("%s\n",buffer);
                std::string server_listen_port(buffer);
                int pos=server_listen_port.find("=");
                std::string portstr=server_listen_port.substr(pos+1,server_listen_port.size()-pos);
                std::string msg="ok";
                if(portstr.empty())
                {
                    printf("server's listen port error\n");
                    msg="not ok...";
                }
                //发送给服务端
                
                int nbytes=msg.size();
                printf("即将发送%d个字节\n",nbytes);
                int nw=write(sockfd_accepted,msg.c_str(),nbytes);
                if(nw!=nbytes)
                {
                    printf("写入socket失败\n");
                }
                else
                {
                    Servers_on_line.push_back(Server(inet_ntoa(server_addr.sin_addr),std::stoi(portstr)));
                }
            }
            else
            {

            }            

        }
    }
    close(sockfd);

    printf("server will be closed!\n");
    return (void*)0;
}

int get_server_info(std::string& ip,unsigned short int& port)
{
    //获取一个可用的server的ip和port
    if(Servers_on_line.empty())
    {
        ip="";
        port=0;
        printf("now no server on line\n");
        return -1;
    }
    int id=rand()%Servers_on_line.size();
    ip=Servers_on_line[id].ip_;
    port=Servers_on_line[id].port_;
    return 0;
}

 server.h

#include <string>

class Server
{

public:
    Server(std::string ip,unsigned short int port);
    ~Server();
public:
    std::string ip_;
    unsigned short int port_;
};

Server::Server(std::string ip,unsigned short int port):ip_(ip),port_(port)
{
}

Server::~Server()
{
}



这篇关于linux网络编程-多client多server一个watcher的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程