其实就是简单的TCP连接,使用了thread库实现多线程,包括使用了类成员函数作为线程函数,传递参数,使用detach将子线程作为后台线程运行,主线程持续接收新的连接
服务端代码:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <vector>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <iostream>
using namespace std;
class ChatServ{
public:
ChatServ(int port){
servIP.sin_family = AF_INET;
servIP.sin_port = htons(port);
servIP.sin_addr.s_addr = htonl(INADDR_ANY);
this->sockfd = socket(AF_INET,SOCK_STREAM,0);
//assert(sockfd == 0);
}
~ChatServ(){}
public:
int chatBind();
int chatListen(int maxbacklog);
void chatAccept();
void func(int connfd);
void servRun();
private:
int sockfd;
struct sockaddr_in servIP;
};
int ChatServ::chatBind(){
int ret = bind(sockfd,(struct sockaddr*)&servIP,sizeof(servIP));
assert(ret == 0);
return 0;
}
int ChatServ::chatListen(int maxbacklog){
int ret = listen(sockfd,maxbacklog);
assert(ret == 0);
return 0;
}
void ChatServ::chatAccept(){
struct sockaddr_in clitAddr;
socklen_t clitLen = sizeof(clitAddr);
while(1){ //主线程持续等待新的连接
int connfd = accept(sockfd,(struct sockaddr*)&clitAddr,&clitLen);
std::thread mythread(std::mem_fn(&ChatServ::func),this,connfd); //这里的使用类成员函数需要特别注意了解
mythread.detach();
}
}
//子线程入口函数 收发数据
void ChatServ::func(int connfd){
//read/send
while(1){
char buffer[1024];
memset(buffer,0,sizeof(buffer));
int ret = recv(connfd,buffer,sizeof(buffer),0);
if(ret){
cout<<"ret clit:"<<buffer<<endl;
char sendBuf[1024];
memset(sendBuf,0,sizeof(sendBuf));
cout<<"Please Input:"<<endl;
cin>>sendBuf;
send(connfd,sendBuf,sizeof(sendBuf),0);
}else if(ret == 0){
cout<<"link failure!"<<endl; //断开连接
close(connfd);
break;
}
}
close(sockfd);
}
void ChatServ::servRun(){
chatBind();
chatListen(5);
chatAccept();
}
int main(int argc,char *argv[]){
ChatServ serv(6666);
serv.servRun();
return 0;
}
客户端代码:
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <iostream>
#include <string>
#include <cassert>
#include <sys/types.h>
#include <netinet/in.h> //htons
#include <string.h> // memset
#include <arpa/inet.h> // inet_addr
using namespace std;
int main(){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
// assert(sockfd == 0);
struct sockaddr_in servAddr;
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(6666);
servAddr.sin_addr.s_addr = inet_addr("192.168.10.128");
int ret = connect(sockfd,(struct sockaddr*)&servAddr,sizeof(servAddr));
assert(ret == 0);
while(1){
char sendbuffer[1024];
memset(sendbuffer,0,sizeof(sendbuffer));
// int ret = recv(sockfd,buffer,sizeof(buffer),0);
//
cout<<"Please Input:"<<endl;
cin>>sendbuffer;
send(sockfd,sendbuffer,sizeof(sendbuffer),0);
char recvbuf[1024];
int ret = recv(sockfd,recvbuf,sizeof(recvbuf),0);
if(ret){
cout<<"recv serv:"<<recvbuf<<endl;
}else if(ret == 0){
cout<<"link failure!"<<endl; //duankai
close(sockfd);
break;
}
}
}
结果:
这里只是很简单的一个多线程连接 ,收发数据测试一下, 具体的数据处理并没有处理。所以不能收发带有空格等分隔符的数据 只是连续的字符
编译: g++ 源代码.cpp -o 执行名字 -pthread
eg: g++ chatApp.cpp -o test -pthread