简单的socket编程C++代码(已测试)

简单的socket服务器端和客户端程序,实现但server多client连接

只作参考作用,比较初级

server代码:

#include"socket.h"
///////////////////////////////////////////////////////////////////////////////////
tcpserver::tcpserver()
{
  MaxFD = -1;    
  server_sock_fd = -1;
  backlog = 4;            //完成三次握手但没有accept的队列的长度
  UsrPara.tv.tv_sec = 5;    
  UsrPara.tv.tv_usec = 0; 
  UsrPara.ip = "127.0.0.1";
  UsrPara.port = 11345;
  UsrPara.MaxConnect = 10;      //应用层同时可以处理的连接    
  UsrPara.BuffSize = 1024;   
  UsrPara.CmdQuit = "stop";
}
///////////////////////////////////////////////////////////////////////////////////
tcpserver::~tcpserver()
{
  delete[](send_msg);
  delete[](recv_msg);
  delete[](client_fd_arr);
}
///////////////////////////////////////////////////////////////////////////////////
bool tcpserver::LoadPara(serverpara U_P)
{
  if(!((U_P.tv.tv_sec == 0)&&(U_P.tv.tv_usec == 0))){UsrPara.tv.tv_sec = U_P.tv.tv_sec;UsrPara.tv.tv_usec = U_P.tv.tv_usec;}  
  if(0 != U_P.ip.compare("")){UsrPara.ip = U_P.ip;}
  if(0 != U_P.port){UsrPara.port = U_P.port;}
  if(0 != U_P.MaxConnect){UsrPara.MaxConnect = U_P.MaxConnect;}
  if(0 != U_P.BuffSize){UsrPara.BuffSize = U_P.BuffSize;}
  if(0 != U_P.CmdQuit.compare("")){UsrPara.CmdQuit = U_P.CmdQuit;}
  
  send_msg = new char[UsrPara.BuffSize];    
  recv_msg = new char[UsrPara.BuffSize];
  client_fd_arr = new int[UsrPara.BuffSize];
  return 1;
}
///////////////////////////////////////////////////////////////////////////////////
bool tcpserver::CreateLink()
{
    //本地地址    
    struct sockaddr_in server_addr;    
    server_addr.sin_family = AF_INET;    
    server_addr.sin_port = htons(UsrPara.port);    
    server_addr.sin_addr.s_addr = inet_addr(UsrPara.ip.c_str());    
    bzero(&(server_addr.sin_zero), 8);    
    //创建socket    
    server_sock_fd = socket(AF_INET, SOCK_STREAM, 0);    
    if(server_sock_fd == -1){ printf("socket error");return false;}    
    //绑定socket    
    int bind_result = bind(server_sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));    
    if(bind_result == -1){printf("bind error");return false;}    
    //listen    
    if(listen(server_sock_fd, backlog) == -1){printf("listen error");return false;}    
    return true;
}
///////////////////////////////////////////////////////////////////////////////////
int tcpserver::SetMonitor()
{   
    struct timeval OutTime;
    OutTime.tv_sec = UsrPara.tv.tv_sec;
    OutTime.tv_usec = UsrPara.tv.tv_usec;
    
    FD_ZERO(&server_fd_set);    
    FD_SET(STDIN_FILENO, &server_fd_set);    
    if(MaxFD     //服务器端socket    
    FD_SET(server_sock_fd, &server_fd_set);   
    if(MaxFD < server_sock_fd){MaxFD = server_sock_fd;}    
    //客户端连接
    for(int i =0; i < UsrPara.MaxConnect; i++)    
    {  
        if(client_fd_arr[i] != 0)    
        {    
        FD_SET(client_fd_arr[i], &server_fd_set);    
        if(MaxFD < client_fd_arr[i]){MaxFD = client_fd_arr[i];}    
        }    
    }
    
        int ret = select(MaxFD + 1, &server_fd_set, NULL, NULL, &OutTime);    
        if(ret < 0){printf("ERR : tcp server select error\n");return ret;}    
//        else if(ret == 0){printf("ERR : tcp server select overtime\n");return 0;} 
        return 1;
}  
/////////////////////////////////////////////////////////////////////////////////// 
int tcpserver::DealMonitor()
{
    //有新的输入
        if(FD_ISSET(STDIN_FILENO, &server_fd_set))    
        {    
        printf("发送消息:%s\n",send_msg);    
                bzero(send_msg, UsrPara.BuffSize);    
                fgets(send_msg, UsrPara.BuffSize, stdin);
        string mid(send_msg,UsrPara.CmdQuit.size());
                //输入“stop"则退出服务器    
                if(0 == mid.compare(UsrPara.CmdQuit)){return -1;}
                for(int i = 0; i < UsrPara.MaxConnect; i++)    
                {    
                    if(client_fd_arr[i] != 0){printf("client_fd_arr[%d]=%d\n", i, client_fd_arr[i]);send(client_fd_arr[i], send_msg, UsrPara.BuffSize, 0);}    
                }    
        } 
        //有新的连接请求
        if(FD_ISSET(server_sock_fd, &server_fd_set))    
        {
                struct sockaddr_in client_address;    
                socklen_t address_len;    
                int client_sock_fd = accept(server_sock_fd, (struct sockaddr *)&client_address, &address_len);    
                printf("提示 : new connection client_sock_fd = %d\n", client_sock_fd);    
                if(client_sock_fd > 0)    
                {    
                    int index = -1;    
                    for(int i = 0; i < UsrPara.MaxConnect; i++)    
                    {    
                        if(client_fd_arr[i] == 0){index = i;client_fd_arr[i] = client_sock_fd;return 0;}    
                    }    
                    if(index >= 0)
            {printf("提示 : 新客户端(%d)加入成功 %s:%d\n", index, inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port));}    
                    else    
                    {    
                        bzero(send_msg, UsrPara.BuffSize);    
                        strcpy(send_msg, "提示 : 服务器加入的客户端数达到最大值,无法加入!\n");    
                        send(client_sock_fd, send_msg, UsrPara.BuffSize, 0);    
                        printf("提示 : 客户端连接数达到最大值,新客户端加入失败 %s:%d\n", inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port));    
                    }    
                }    
          }    
          for(int i =0; i < UsrPara.MaxConnect; i++)    
          {    
                if(client_fd_arr[i] !=0)    
                {    
                    if(FD_ISSET(client_fd_arr[i], &server_fd_set))    
                    {    
                        //处理某个客户端过来的消息    
                        bzero(recv_msg, UsrPara.BuffSize);    
                        long byte_num = recv(client_fd_arr[i], recv_msg, UsrPara.BuffSize, 0);    
                        if (byte_num > 0)    
                        {    
                            if(byte_num > UsrPara.BuffSize){byte_num = UsrPara.BuffSize;}    
                            recv_msg[byte_num] = '\0';    
                            printf("提示 : 客户端(%d):%s\n", i, recv_msg);    
                        }    
                        else if(byte_num < 0){printf("提示 : 从客户端(%d)接受消息出错.\n", i);}    
                        else    
                        {    
                            FD_CLR(client_fd_arr[i], &server_fd_set);    
                            client_fd_arr[i] = 0;    
                            printf("提示 : 客户端(%d)退出了\n", i);    
                        }    
                    }    
                }    
          }
          
      return 1;
}
/////////////////////////////////////////////////////////////////////////////////// 
void tcpserver::RUN()
{
    long int MidTime=0,ContrastTime=0;
    int SetRet=0,DealRet=0;state = 0;
    int nowtime[8] = {0};
    if(!CreateLink()){printf("***tcp server run fail***\n");return;}
    while(state == 0)
    {
        SetRet = SetMonitor();
        if(SetRet<0){printf("***tcp server run fail***\n");break;}
        else if(SetRet>0);
        {
            DealRet = DealMonitor();
            if(DealRet == -1){printf("提示 : ***manual shut down tcp server service***\n");break;}
        }
        MidTime = NowTime(nowtime);
        if(MidTime-ContrastTime>4)
        {
            ContrastTime = MidTime;
            printf("%d-%02d-%02d %02d:%02d:%02d   : 提示 : tcp server running ...\n",nowtime[0],nowtime[1],nowtime[2],nowtime[3],nowtime[4],nowtime[5]);
        }
    }
    return;
}
/////////////////////////////////////////////////////////////////////////////////// 
void tcpserver::STOP()
{
    state = 1;
    printf("提示 : ***auto shut down server service***\n");
}
///////////////////////////////////////////////////////////////////////////////////
long int tcpserver::NowTime(int *dest)
{
    long int RET;
    time_t nowtime;
    struct timeval tv;    
    gettimeofday(&tv,NULL);
    RET = tv.tv_sec;
//    RET = tv.tv_sec * 1000 + tv.tv_usec / 1000;

    time(&nowtime);
    tm* t= localtime(&nowtime);
    
    dest[0] = t->tm_year + 1900;
    dest[1] = t->tm_mon + 1;
    dest[2] = t->tm_mday;
    dest[3] = t->tm_hour;
    dest[4] = t->tm_min;
    dest[5] = t->tm_sec;
    return RET;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

server主函数调用部分:

#include
#include "socket.h"

int main(int argc, char **argv) {
    
    serverpara PARAOBJ;
    tcpserver OBJ;
    OBJ.LoadPara(PARAOBJ);
    OBJ.RUN();
    return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

client代码:

#include"tcpclient.h"
tcpclient::tcpclient()
{  
    server_sock_fd = -1;
    UsrPara.tv.tv_sec = 5;    
    UsrPara.tv.tv_usec = 0; 
    UsrPara.ip = "127.0.0.1";
    UsrPara.port = 11345;
    UsrPara.MaxConnect = 10;      //应用层同时可以处理的连接    
    UsrPara.BuffSize = 1024;   
    UsrPara.CmdQuit = "stop";
}
///////////////////////////////////////////////////////////////////////////////////
tcpclient::~tcpclient()
{
    delete[](send_msg);
    delete[](recv_msg);
}
///////////////////////////////////////////////////////////////////////////////////
bool tcpclient::ClientLoadPara(clientpara U_P)
{
    if(!((U_P.tv.tv_sec == 0)&&(U_P.tv.tv_usec == 0))){UsrPara.tv.tv_sec = U_P.tv.tv_sec;UsrPara.tv.tv_usec = U_P.tv.tv_usec;}  
    if(0 != U_P.ip.compare("")){UsrPara.ip = U_P.ip;}
    if(0 != U_P.port){UsrPara.port = U_P.port;}
    if(0 != U_P.MaxConnect){UsrPara.MaxConnect = U_P.MaxConnect;}
    if(0 != U_P.BuffSize){UsrPara.BuffSize = U_P.BuffSize;}
    if(0 != U_P.CmdQuit.compare("")){UsrPara.CmdQuit = U_P.CmdQuit;}
    
    send_msg = new char[UsrPara.BuffSize];    
    recv_msg = new char[UsrPara.BuffSize];
    return 1;
}
///////////////////////////////////////////////////////////////////////////////////
bool tcpclient::ClientCreateLink()
{
    server_addr.sin_family = AF_INET;    
    server_addr.sin_port = htons(UsrPara.port);    
    server_addr.sin_addr.s_addr = inet_addr(UsrPara.ip.c_str());    
    bzero(&(server_addr.sin_zero), 8);    
    //创建socket    
    server_sock_fd = socket(AF_INET, SOCK_STREAM, 0);    
    if(server_sock_fd == -1){ printf("client socket error");return false;}   
    if(connect(server_sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) == 0)   
    return true;
}
///////////////////////////////////////////////////////////////////////////////////
int tcpclient::ClientSetMonitor()

    struct timeval OverTime;
    OverTime.tv_sec = UsrPara.tv.tv_sec;
    OverTime.tv_usec = UsrPara.tv.tv_usec;
    FD_ZERO(&client_fd_set);    
    FD_SET(STDIN_FILENO, &client_fd_set);
    FD_SET(server_sock_fd, &client_fd_set);
    int ret = select(server_sock_fd + 1, &client_fd_set, NULL, NULL, &OverTime);
    if(ret < 0){printf("ERR : tcp client select error\n");return ret;}    
//        else if(ret == 0){printf("ERR : tcp client select overtime\n");return 0;}
        return 1;
}
///////////////////////////////////////////////////////////////////////////////////
int tcpclient::ClientDealMonitor()
{
    if(FD_ISSET(STDIN_FILENO, &client_fd_set))    
        {    
            bzero(send_msg, UsrPara.BuffSize);    
            fgets(send_msg, UsrPara.BuffSize, stdin);
        string mid(send_msg,UsrPara.CmdQuit.size());
            //输入“stop"则退出服务器    
            if(0 == mid.compare(UsrPara.CmdQuit)){return -1;}
            if(send(server_sock_fd, send_msg, UsrPara.BuffSize, 0) == -1){printf("提示 : 发送消息失败!\n");}    
        }  
    if(FD_ISSET(server_sock_fd, &client_fd_set))    
        {    
            bzero(recv_msg, UsrPara.BuffSize);    
            long byte_num = recv(server_sock_fd, recv_msg, UsrPara.BuffSize, 0);    
            if(byte_num > 0)    
            {    
        if(byte_num > UsrPara.BuffSize){byte_num = UsrPara.BuffSize;}    
        recv_msg[byte_num] = '\0';    
        printf("提示 : 服务器的应答:%s\n", recv_msg);
            }    
            else if(byte_num < 0){printf("接受消息失败!\n");return -2;}    
            else{printf("提示 : 服务器未运行!\n");return -3;}    
        }
}
/////////////////////////////////////////////////////////////////////////////////// 
void tcpclient::CLIENTRUN()
{
    long int MidTime=0,ContrastTime=0;
    int SetRet=0,DealRet=0;state = 0;
    int nowtime[8] = {0};
    if(!ClientCreateLink()){printf("***tcp client run fail***\n");return;}
    while(state == 0)
    {
        SetRet = ClientSetMonitor();
        if(SetRet<0){printf("***tcp client run fail***\n");break;}
//        else if(state == 0){printf("***communication timeout***\n");}
        else if(SetRet>0);
        {
            DealRet = ClientDealMonitor();
            if(DealRet == -1){printf("提示 : ***manual shut down tcp server service***\n");break;}
            if(DealRet == -3){printf("提示 : ***passive turn off this client***\n");break;}
        }
        MidTime = NowTime(nowtime);
        if(MidTime-ContrastTime>4)
        {
            ContrastTime = MidTime;
            printf("%d-%02d-%02d %02d:%02d:%02d   : 提示 : tcp client running ...\n",nowtime[0],nowtime[1],nowtime[2],nowtime[3],nowtime[4],nowtime[5]);
        }
    }
    return;
}
/////////////////////////////////////////////////////////////////////////////////// 
void tcpclient::CLIENTSTOP()
{
    state = 1;
    printf("提示 : ***auto shut down server service***\n");
    return;
}
///////////////////////////////////////////////////////////////////////////////////
long int tcpclient::NowTime(int *dest)
{
    long int RET;
    time_t nowtime;
    struct timeval tv;    
    gettimeofday(&tv,NULL);
    RET = tv.tv_sec;
//    RET = tv.tv_sec * 1000 + tv.tv_usec / 1000;

    time(&nowtime);
    tm* t= localtime(&nowtime);
    
    dest[0] = t->tm_year + 1900;
    dest[1] = t->tm_mon + 1;
    dest[2] = t->tm_mday;
    dest[3] = t->tm_hour;
    dest[4] = t->tm_min;
    dest[5] = t->tm_sec;
    return RET;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

client主函数调用部分:

#include
#include "tcpclient.h"
int main(int argc, char **argv){
    clientpara PARA;
    tcpclient OBJ;
    OBJ.ClientLoadPara(PARA);
    OBJ.CLIENTRUN();
    return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

小提示:select函数超时设置,和被监控的套接字文件在调用select函数后会被清除,所以循环select函数之前必须重新载入超时时间和被监控的套接字,否则select会超时。

你可能感兴趣的:(简单的socket编程C++代码(已测试))