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()
{
}
标签:addr,int,watcher,client,linux,sockfd,server,port 来源: https://blog.csdn.net/xiyangxiaoguo/article/details/121709339