Linux下Socket编程(二)——多线程封装

简介

  • 客户端连接后放到线程中运行
  • Socket相关代码封装

C++线程

这里使用c++11标准的线程库。

#include 

编译时候出现

thread_1.png

根据错误提示编译命令后加入 -std=c++0x即可,对于使用的线程需要引入库 -lpthread

线程使用

线程的调用我们定义一个SocketThread类来进行

SocketThread* st=new SocketThread(connfd);
thread t(&SocketThread::run,st);
t.detach();

然后我们将数据读取的方法放到SocketThread中

    void run(){
        int n=0;
        cout<<"new thread for socket "<sock<sock,buff,1024,0);
                if(n<=0) {
                        //如果客户端断开了,这里就跳出循环
                        break;
                }
                buff[n] = '\0';
                printf("%d=>%s",n,buff);
        }
        close(this->sock);
        cout<sock<<" closed"<
注意

当我么使用c++的语法,并使用std命名空间后发现客户端连不上服务端。这里是bind方法出现了问题。使用了命名空间中的bind。这里需要是用全局的bind方法::bind即可。

Socket相关类封装

这里我们将客户端和服务的的操作封装到一个类XTcp中,服务的接受连接后,生成一个新的Tcp对象,并将指针返回,然后线程类XThread持有XTcp的指针。

XTcp.h
#include 
using namespace std;

class XTcp{
private:
  int sock;

public:
  XTcp();
  void setSock(int sock);
  int getSock();
  int createSocket();
  int bindPort(unsigned short port);
  int listenSocket();
  int receive(char *buf,int len);
  int sendData(char *buf,int len);
  int connectServer(int port);
  XTcp* acceptClient();
  int closeSocket();
  ~XTcp();
};
XTcp.cpp
#include "XTcp.h"
#include "stdio.h"
//socket相关函数需要
#include 
#include 
//close函数需要
#include 
#include 
#include 
#include 
#include 
//c++ 11标准线程
#include 
#include "XThread.h"
XTcp::XTcp(){
        sock=-1;
}

void XTcp::setSock(int sock){
        this->sock=sock;
}
int XTcp::getSock(){
        return this->sock;
}

int XTcp::createSocket(){
        //创建一个socket
        this->sock=socket(AF_INET,SOCK_STREAM,0);
        if(this->sock==-1) {
                cout<<"create socket failed"<sock;
}
int XTcp::bindPort(unsigned short port){
        struct sockaddr_in sockaddr;
        memset(&sockaddr,0,sizeof(sockaddr));
        sockaddr.sin_family=AF_INET;
        sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
        sockaddr.sin_port=htons(port);
        ::bind(sock,(struct sockaddr *)&sockaddr,sizeof(sockaddr));
        return 0;
}

/**
* 开始监听
*/
int XTcp::listenSocket(){
        listen(sock,10);
        return 0;
}

/**
 *  接受客户端的连接,如果连接成功就返回连接后的XTcp
 */
XTcp* XTcp::acceptClient(){
        int connfd;
        struct sockaddr_in sockaddrClient;
        int clientl=sizeof(sockaddrClient);
        printf("wait for client connect\n" );
        // if((connfd = accept(sock,NULL,NULL))==-1) {
        if((connfd = accept(sock,(struct sockaddr*)&sockaddrClient,(socklen_t *)&clientl))==-1) {
                printf("accpet socket error: %s errno :%d\n",strerror(errno),errno);
        }
        char cilentIp[20];
        unsigned short port= ntohs(sockaddrClient.sin_port);
        const char *ip=inet_ntop(AF_INET,(void *)&sockaddrClient.sin_addr,cilentIp,16);
        printf("client=> %s:%d\n",cilentIp,port);
        XTcp* xTcpClient=new XTcp;
        xTcpClient->setSock(connfd);
        //开启线程接受数据
        XThread* st=new XThread(xTcpClient);
        thread t(&XThread::run,st);
        t.detach();
        return xTcpClient;
}

int XTcp::connectServer(int port){
        const char * serverIp="127.0.0.1";
        sockaddr_in sockaddr;
        memset(&sockaddr,0,sizeof(sockaddr));
        sockaddr.sin_family = AF_INET;
        sockaddr.sin_port = htons(port);
        //转换ip地址
        inet_pton(AF_INET,serverIp,&sockaddr.sin_addr);
        if((connect(sock,(struct sockaddr*)&sockaddr,sizeof(sockaddr))) < 0 )
        {
                printf("connect error :[%s] errno: %d\n",strerror(errno),errno);
                exit(0);
        }
        cout<<"send msg to server:"<sock,buf,len,0);
        return n;
}

/**
* 发送数据
*/
int XTcp::sendData(char *buf,int len){
        if(sock<0) {
                cout<<"socket is invalid"<
XThread.h
#include 
using namespace std;
class XThread {
private:
XTcp* sock;
public:
XThread(XTcp* sock){
        this->sock=sock;
}
~XThread(){
        cout<<"release"<sock->getSock()<receive(buff,1024);
                if(n<=0) {
                        //如果客户端断开了,这里就跳出循环
                        break;
                }
                buff[n] = '\0';
                printf("%d=>%s",n,buff);
        }
        sock->closeSocket();
}
};
Makefile
all: xserver xclient

xserver : xserver.cpp XTcp.h XTcp.cpp XThread.h
    g++ -lpthread -o xserver xserver.cpp XTcp.cpp  -std=c++0x

xclient : xclient.cpp XTcp.h XTcp.cpp
    g++ -o $@ $+ -std=c++0x

.PHONY : clean
clean :
    -rm  xserver xclient

你可能感兴趣的:(Linux下Socket编程(二)——多线程封装)