服务端代码:
感觉和select区别不大,而且不能像select那样跨平台
/*************************************************************************
> File Name: server.cpp
> Author: chencj
> Mail: 1378755306@qq.com
> Created Time: 2020年08月05日 星期三 09时49分18秒
************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstdlib>
#include <poll.h>
const int N = 128;
const int Max_Size = 1024;
static int Maxi = 0;
void sys_err(std::string msg) //出错函数
{
perror(msg.c_str());
exit(1);
}
class Server{
private:
int num; //记录连接客户端的数量
int lfd,cfd; //监听套接字 通信套接字
struct sockaddr_in server_addr,client_addr; //服务端 客户端地址结构
struct pollfd pfd[Max_Size]; //监听集合
char buf[N];
public:
Server():num(0){}
~Server(){}
void CreateSock(); //建立套接字
void CreateAddr(const char *,const char *); //设置地址结构
void Listen_Bind(); //绑定 监听
void solve(); //通信
};
void Server::CreateSock()
{
lfd = socket(AF_INET,SOCK_STREAM,0);
if(lfd == -1) sys_err("socket error\n");
}
void Server::CreateAddr(const char *IP,const char* PORT)
{
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_addr.s_addr = inet_addr(IP);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(PORT));
}
void Server::Listen_Bind()
{
int vel = 1;
setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,(void*)&vel,sizeof(vel));
if(bind(lfd,(struct sockaddr*)&server_addr,sizeof(server_addr)) == -1)
sys_err("bind error\n");
if(listen(lfd,N) == -1)
sys_err("listen error\n");
}
void Server::solve()
{
socklen_t clen = sizeof(client_addr);
pfd[0].fd = lfd;
pfd[0].events = POLLIN;
for(int i=1;i<Max_Size;i++)
pfd[i].fd = -1;
while(1)
{
int ret;
ret = poll(pfd,Maxi+1,-1);
if(ret < 0) sys_err("poll error\n");
else if(ret > 0)
{
if(pfd[0].revents & POLLIN) {
cfd = accept(lfd,(struct sockaddr*)&client_addr,&clen);
if(cfd == -1) sys_err("accept error\n");
++num;
printf("[ip : %s--port : %d]--%d connect\n",inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port),num);
if(num == Max_Size) sys_err("over Max_Size\n");
for(int i=1;i<Max_Size;i++) {
if(pfd[i].fd == -1) {
pfd[i].fd = cfd;
pfd[i].events = POLLIN;
if(i > Maxi) Maxi = i;
break;
}
}
if(ret == 1) continue;
}
for(int i=1;i<=Maxi;i++)
{
if(pfd[i].fd == -1) continue;
if(pfd[i].revents & POLLIN) {
memset(buf,'\0',sizeof(buf));
int data = read(pfd[i].fd,buf,sizeof(buf));
if(data == -1) sys_err("read error\n");
if(data == 0) {
pfd[i].fd = -1;
close(pfd[i].fd);
printf("One Disconnect----%d client remains\n",--num);
}
else {
printf("[ip : %s--port : %d]--data : %s\n",inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port),buf);
write(pfd[i].fd,"Accept",7);
}
}
}
}
}
close(lfd);
}
int main(int argc, char const *argv[])
{
if(argc < 3) sys_err("input error\n");
Server T = Server(); //一个server对象
T.CreateSock();
T.CreateAddr(argv[1],argv[2]);
T.Listen_Bind();
T.solve();
return 0;
}
客户端代码:
/*************************************************************************
> File Name: client.cpp
> Author: chencj
> Mail: 1378755306@qq.com
> Created Time: 2020年08月05日 星期三 09时49分28秒
************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
const int N = 128;
void sys_err(std::string msg)
{
perror(msg.c_str());
exit(1);
}
class Client{
private:
int sockfd;
struct sockaddr_in client_addr;
char buf[N],recv_buf[N];
public:
Client(){}
~Client(){};
void CreateSock();
void CreateAddr(const char*,const char*);
void slove();
};
void Client::CreateSock()
{
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1) sys_err("socket error\n");
}
void Client::CreateAddr(const char *IP,const char *PORT)
{
bzero(&client_addr,sizeof(client_addr));
client_addr.sin_addr.s_addr = inet_addr(IP);
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(atoi(PORT));
}
void Client::slove()
{
if(connect(sockfd,(struct sockaddr*)&client_addr,sizeof(client_addr)) == -1)
sys_err("connect error\n");
std::cout<<"------Connect---------\n";
memset(buf,'\0',sizeof(buf));
while(fgets(buf,N,stdin) != NULL)
{
write(sockfd,buf,sizeof(buf));
memset(recv_buf,'\0',sizeof(recv_buf));
read(sockfd,recv_buf,sizeof(recv_buf));
std::cout<<recv_buf<<std::endl;
if(memcmp("###",buf,3) == 0) {
std::cout<<"------Disconnect------"<<std::endl;
break;
}
memset(buf,'\0',sizeof(buf));
}
close(sockfd);
}
int main(int argc, char const *argv[])
{
Client T = Client();
T.CreateSock();
T.CreateAddr(argv[1],argv[2]);
T.slove();
return 0;
}
测试结果