[VC++] socket网络传输

不研究TCP/IP协议,没有三次握手,不说 物数网传会表应(只要大学学过计算机基础的都背过吧!)这七层。

封装好socket。

server:

class ServerSock
{
public:
    ServerSock();
    ~ServerSock();
    SOCKET getClient() {return sClient;};

private:
    static const int PORT = 10086;
    int             retVal;         //返回值 
    SOCKET          sServer;        //服务器套接字  
    SOCKET          sClient;        //客户端套接字  
    SOCKADDR_IN     addrServ;;      //服务器地址  
};

ServerSock::ServerSock()
{
    WSADATA wsd;            //WSADATA变量  
    //初始化套结字动态库  
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)  
    {  
        cout << "WSAStartup failed!" << endl;  
    }  
    //创建套接字  
    sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);      
    if(INVALID_SOCKET == sServer)  
    {  
        cout << "socket failed!" << endl;  
        WSACleanup();//释放套接字资源;  
    }  
    //服务器套接字地址   
    addrServ.sin_family = AF_INET;  
    addrServ.sin_port = htons(PORT);  
    addrServ.sin_addr.s_addr = INADDR_ANY;        
    //绑定套接字  
    retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));  
    if(SOCKET_ERROR == retVal)  
    {     
        cout << "bind failed!" << endl;  
        closesocket(sServer);   //关闭套接字  
        WSACleanup();           //释放套接字资源;  
    }  
    //开始监听   
    cout<<"start listen!"<<endl;
    retVal = listen(sServer, 1);  
    if(SOCKET_ERROR == retVal)  
    {  
        cout << "listen failed!" << endl;         
        closesocket(sServer);   //关闭套接字  
        WSACleanup();           //释放套接字资源;  
    }  
    //接受客户端请求  
    sockaddr_in addrClient;  
    int addrClientlen = sizeof(addrClient);  
    sClient = accept(sServer,(sockaddr FAR*)&addrClient, &addrClientlen);  
    cout<<"accept!"<<endl;
    if(INVALID_SOCKET == sClient)  
    {  
        cout << "accept failed!" << endl;         
        closesocket(sServer);   //关闭套接字  
        WSACleanup();           //释放套接字资源;  
    } 
}

ServerSock::~ServerSock()
{
    closesocket(sServer);   //关闭套接字  
    //closesocket(sClient);   //关闭套接字  
    WSACleanup();            //释放套接字资源;  
}

client:

class ClientSock
{
public:
    ClientSock();
    ~ClientSock();
    SOCKET getClient() {return cClient;};

private:
    static const int PORT = 10086;
    int             retVal;         //返回值 
    SOCKET          cClient;        //客户端套接字  
    SOCKADDR_IN     addrServ;;      //服务器地址  
};

ClientSock::ClientSock()
{
    WSADATA wsd;            //WSADATA变量  
    //初始化套结字动态库  
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)  
    { 
        cout << "WSAStartup failed!" << endl;  
    }  
    //创建套接字  
    cClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);      
    if(INVALID_SOCKET == cClient)  
    {  
        cout << "socket failed!" << endl;  
        WSACleanup();//释放套接字资源;  
    }  
    //服务器套接字地址   
    addrServ.sin_family = AF_INET;  
    addrServ.sin_port = htons(PORT);  
    addrServ.sin_addr.s_addr = inet_addr(IP_ADDR);        
    //绑定套接字  
    retVal = connect(cClient, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));  
    if(SOCKET_ERROR == retVal)  
    {     
        cout << "connect failed!" << endl;  
        closesocket(cClient);   //关闭套接字  
        WSACleanup();           //释放套接字资源;  
    }  
}

ClientSock::~ClientSock()
{
    //closesocket(cClient);   //关闭套接字  
    WSACleanup();            //释放套接字资源;  
}

关于数据部分,两个是通用的

class SockData
{
public:
    SockData(SOCKET _client) { client = _client;};
    ~SockData()  { closesocket(client); };
    bool sendData(const char sData);
    bool sendData(int sData);
    bool sendData(char* sData,int Len = BUFSIZE);
    bool sendData(const string sfileRoad);
    int recvData();
    bool recvData(char* buf, int Len = BUFSIZE);
    bool recvData(const string rfileRoad);

private:
    static const int BUFSIZE = 1024;        //默认大小
    int             retVal;         //返回值 
    SOCKET          client;        //客户端套接字  
};


bool SockData::sendData(const char sData)
{
    retVal = send(client,&sData,sizeof(char),0);
    if(retVal==SOCKET_ERROR)
    {
        cout<<"Send Into error: "<<GetLastError()<<endl;
        cout<<"Fail char: "<<sData<<endl;
        return false;
    }
    return true;
}

bool SockData::sendData(int sData)
{
    stringstream strTemp;strTemp.clear();strTemp.str("");
    strTemp << sData;
    const string sTemp = strTemp.str();
    const char* cTemp = sTemp.c_str();
    if(! sendData(char('0'+strlen(cTemp))))
    {
        cout<<"In trouble"<<endl;
    }
    retVal = send(client,cTemp,sizeof(char) * strlen(cTemp),0);
    if(retVal==SOCKET_ERROR)
    {
        cout<<"Send Into error: "<<GetLastError()<<endl;
        cout<<"Fail int: "<<sData<<endl;
        return false;
    }
    return true;
}

bool SockData::sendData(char* sData,int Len)
{
    retVal=send(client,sData,sizeof(char) * Len,0);
    if(retVal==SOCKET_ERROR)
    {
        cout<<"Send Into error: "<<GetLastError()<<endl;
        return false;
    }
    return true;
}

bool SockData::sendData(const string sfileRoad)
{
    ifstream in(sfileRoad,fstream::in|fstream::binary);
    if(!in.is_open())
    {
        cout<<"fail open file."<<endl;
        return false;
    }
    in.seekg (0, ios::end);  
    int length = in.tellg();  
    in.seekg (0, ios::beg); 

    sendData(length);
    char* buf = new char[BUFSIZE];  //接收数据缓冲区  
    ZeroMemory(buf, BUFSIZE);

    while(!in.eof())
    {
        in.read(buf,BUFSIZE);
        retVal=send(client,buf,sizeof(char) * BUFSIZE,0);
        if(retVal==SOCKET_ERROR)
        {
            cout<<"Send Into error: "<<GetLastError()<<endl;
            return false;
        }
    }
    in.close();
    delete[] buf;

    return true;
}

int SockData::recvData()
{
    char intBit;
    retVal = recv(client,&intBit,sizeof(char),0);
    if(retVal == SOCKET_ERROR)
    {
        cout<<"Recv Into error: "<<GetLastError()<<endl;
        cout<<"Fail intBit!"<<endl;
        return false;
    }
    int Bit = atoi(&intBit);
    char* cInt = new char[Bit];
    retVal = recv(client,cInt,sizeof(char) * Bit,0);
    if(retVal == SOCKET_ERROR)
    {
        cout<<"Recv Into error: "<<GetLastError()<<endl;
        cout<<"Fail intBit!"<<endl;
        return false;
    }
    int rData = atoi(cInt);
    delete[] cInt;

    return rData;
}

bool SockData::recvData(char* buf, int Len)
{
    ZeroMemory(buf,Len);
    if(Len <= BUFSIZE)
    {
        retVal = recv(client,buf,sizeof(char) * Len,0);
        if(retVal == SOCKET_ERROR)
        {
            cout<<"Recv Into error: "<<GetLastError()<<endl;
            cout<<"Fail char*!"<<endl;
            return false;
        }
    }
    else
    {
        int rbufReal = 0, rbufNeed = Len;
        while (rbufReal < Len)
        {
            retVal = recv(client,buf,sizeof(char) * BUFSIZE,0);
            if(retVal == SOCKET_ERROR)
            {
                cout<<"Recv Into error: "<<GetLastError()<<endl;
                cout<<"Fail char*!"<<endl;
                return false;
            }
            rbufReal += retVal;
            rbufNeed = Len - rbufReal;
        }
    }

    return true;
}

bool SockData::recvData(const string rfileRoad)
{
    int length = recvData();
    char* buf = new char[BUFSIZE];
    ZeroMemory(buf, BUFSIZE);
    ofstream out(rfileRoad,fstream::out|fstream::binary);
    if(!out.is_open())
    {
        cout<<"don't create file."<<endl;
        return false;
    }
    int rbufReal = 0, rbufNeed = length;
    while (rbufReal < length)
    {
        if(recvData(buf))
        {
            rbufReal += retVal;
            rbufNeed = length - rbufReal;
            out.write(buf,sizeof(char)*retVal);
        }
    }    
    out.close();
    delete[] buf;

    return true;
}

代码托管:https://github.com/zhanxiage1994/VCplusSocket.git

原文地址:https://www.cnblogs.com/zhanxiage1994/p/6674108.html