關於TCP通信的實現(c++)


  TCP通信機制,采用全雙工(就是既可以發送數據,也可以接收數據)的形式進行客戶端和服務器之間的鏈接,並且這是一種可靠數據傳輸(數據在進行收發的過程中並不會進行損失),並非UDP那樣,詳細細節,為什么可靠傳輸,可以參考《計算機網絡——自頂向下》,以下代碼均采用c++的模式進行實現

  1.TCP------Server

#pragma warning(disable:4996);
#include <iostream>
#include<winsock2.h>
#include<windows.h>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
class TCP
{
public:
    void check_version();
    void intintail();
    void blind_listen();
    void sent_recv();
private:
    WSADATA data;
    SOCKET sock_server;
    SOCKET sock_client;
    SOCKADDR_IN add_server;
    SOCKADDR_IN add_client;

    

};
int main()
{
    TCP a;
    a.check_version();
    a.intintail();
    a.blind_listen();
    a.sent_recv();
  
}
void TCP::check_version()
{
// int ret= WSAStartup(MAKEWORD(2,2),&data);
    if (WSAStartup(MAKEWORD(2,2),&data)!=0)
    {
        cout << "套接字的版本錯誤" << endl;
        WSACleanup();
    }
    else
    {
        cout << "套接字版本正確" << endl;
    }
}

void TCP::intintail()
{
    //套接字接口的配置
    sock_server = socket(AF_INET, SOCK_STREAM, 0);
    //配置地址的設置
    add_server.sin_family = AF_INET;
    add_server.sin_port = htons();
    add_server.sin_addr.S_un.S_addr =inet_addr("");//填寫一個Ip地址
} void TCP::blind_listen() { int n = sizeof(SOCKADDR_IN); int ret = bind(sock_server, (LPSOCKADDR)&add_server, n); if (ret==SOCKET_ERROR) { cout << "套接字綁定失敗" << endl; WSACleanup(); } else { cout << "套接字綁定成功" << endl; } //開始監聽套接字 int ret2 = listen(sock_server, 10);//第二個參數決定未完成隊列和已完成隊列中連接數目之和的最大值 if (ret2 == SOCKET_ERROR) { cout << "監聽失敗" << endl; WSACleanup(); } else { cout << "監聽成功" << endl; } } void TCP::sent_recv() { cout << "請稍等。。。" << "\t" << "正在准備鏈接客戶端" << endl; Sleep(3000); while (true) { int len = sizeof(SOCKADDR); //首先開始鏈接客戶端 sock_client = accept(sock_server, (LPSOCKADDR)&add_client, &len); if (sock_client == SOCKET_ERROR) { cout << "鏈接失敗" << endl; WSACleanup(); break; } else { cout << "鏈接成功" << endl; } //進行數據的收發 char ser[100] = "hello client"; if (send(sock_client, ser,100, 0) == SOCKET_ERROR) { cout << "發送失敗" << endl; WSACleanup(); break; } else { cout << "發送成功" << endl; } } }

    2TCP-----Client

#pragma warning(disable:4996);
#include <iostream>
using namespace std;
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include<windows.h>
class TCP
{
public:
    void intalize();
    void my_connect();
    void my_recv();

private:
    SOCKET sock_client;
    SOCKADDR_IN  addr_server;
    SOCKADDR_IN  client_ADDR;
    WSADATA data;
public:char rec[100];//接受並且進行打印的數組
      int len;
};

int main()
{
    TCP a;
    a.intalize();
    a.my_connect();
    a.my_recv();
  
}
void TCP::intalize()
{
    if (WSAStartup(MAKEWORD(2, 2), &data) != 0)
    {
        cout << "套接字的版本錯誤" << endl;
        WSACleanup();
    }
    else
    {
        cout << "套接字版本正確" << endl;
    }
    memset(&addr_server, 0, sizeof(addr_server));
    sock_client=socket(AF_INET, SOCK_STREAM, 0);
    if (sock_client == INVALID_SOCKET)
    {
        cout << "設置失敗" << endl;
        WSACleanup();
    }
    else
    {
        cout << "設置成功" << endl;
    }
    addr_server.sin_family = AF_INET;
    addr_server.sin_port = htons();//選擇一個電腦的任意端口
    addr_server.sin_addr.S_un.S_addr =inet_addr("");//填寫一個Ip地址
    len = sizeof(SOCKADDR_IN);
}

void TCP::my_connect()
{
    if (connect(sock_client,(LPSOCKADDR)&addr_server,len)==SOCKET_ERROR)
    {
        cout << "連接失敗" << endl;
        WSACleanup();
    }
    else
    {
        cout << "連接成功" << endl;
    }
}

void TCP::my_recv()
{

    if (recv(sock_client,rec,1,0)==SOCKET_ERROR)
    {
        cout << "接收失敗" << endl;
        WSACleanup();
    }
    else
    {
        cout << "接收成功" << endl;
        cout << "服務器的信息是:" << rec << endl;
    }
}

  【remark】

對於inet_addr()的調用,在vs2017 和vs2019中若不加上#pragma warning(disable:4996);都會因為版本的問題進行報錯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM