vc++实现的tcp socket客户端和服务端示例

下面是针对“vc++实现的tcp socket客户端和服务端示例”的详细攻略:

一、什么是TCP Socket?

TCP(Transmission Control Protocol)是“传输控制协议”的缩写。它是一种基于连接的、可靠的、面向字节流的传输层协议,主要用于Internet上的数据传输。

Socket是指“套接字”,是一个软件API(Applications Programming Interface),是内核提供的通信机制,并且也是实现网络通信的一个标准。

二、实现TCP Socket客户端和服务端的步骤及对应代码

下面我们将分别介绍实现TCP Socket客户端和服务端的步骤及对应代码。

1. 实现TCP Socket客户端流程

  1. 创建Socket

首先,我们需要在客户端中创建一个Socket,代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    WSADATA wsadata;
    SOCKET sockClient;
    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        return -1;
    }

    sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockClient < 0)
    {
        return -1;
    }
    return 0;
}

在这段代码中,我们使用了WinSock2库中的socket函数来创建Socket。由于TCP是一种面向连接的协议,因此我们在创建Socket时需要指定协议类型(IPPROTO_TCP)和Socket类型(SOCK_STREAM)。

  1. 建立连接

建立连接的过程需要使用到connect函数。connect函数接收服务端地址,用于与服务端建立连接。代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    SOCKADDR_IN addrSrv;
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
    {
        return -1;
    }

    ...
}

在这段代码中,我们首先定义了服务端的地址(包括端口号和IP地址),然后使用connect函数对Socket和服务端进行连接。

  1. 发送和接收数据

连接建立成功后,我们可以使用send函数来发送数据,使用recv函数来接收数据。代码如下:


#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    char buf[] = "Hello World!";
    send(sockClient, buf, strlen(buf), 0);

    char recvBuf[100];
    int len = recv(sockClient, recvBuf, 100, 0);

    ...

    return 0;
}

在这段代码中,我们使用send函数发送了一个字符串(Hello World!),然后使用recv函数接收服务端返回的数据。可以看到,send和recv函数分别需要传入Socket、发送/接收的数据和数据长度等参数。

  1. 关闭Socket

最后,在完成客户端的所有操作后,我们需要使用closesocket函数来关闭Socket。代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    closesocket(sockClient);
    WSACleanup();

    return 0;
}

2. 实现TCP Socket服务端流程

  1. 创建Socket

与客户端类似,我们首先需要在服务端中创建一个Socket,代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    WSADATA wsadata;
    SOCKET sockSrv;
    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        return -1;
    }

    sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockSrv < 0)
    {
        return -1;
    }

    return 0;
}

在这段代码中,我们同样使用了socket函数来创建Socket。

  1. 绑定地址和端口号

接下来,我们需要绑定本地地址和端口号。代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    SOCKADDR_IN addrSrv;
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    addrSrv.sin_addr.s_addr = INADDR_ANY;

    if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
    {
        return -1;
    }

    ...
}

在这段代码中,我们定义了本地地址(包括端口号和IP地址),并使用bind函数将Socket和地址进行绑定。

  1. 监听连接请求

绑定完成后,我们需要使用listen函数监听连接请求。代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    if (listen(sockSrv, 10) < 0)
    {
        return -1;
    }

    ...
}

在这段代码中,我们使用了listen函数来监听连接请求,参数10表示最大连接数。

  1. 接受连接请求

监听完成后,我们通过accept函数接收连接请求。代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);
    SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);

    ...
}

在这段代码中,我们先定义了addrClient来存储客户端地址,然后使用accept函数接受连接请求,返回一个与客户端通信的Socket。

  1. 接收和发送数据

连接成功后,我们可以使用recv函数来接收客户端发送的数据,使用send函数来向客户端发送数据。代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    char recvBuf[100];
    int len = recv(sockConn, recvBuf, 100, 0);

    char buf[] = "Hello Client!";
    send(sockConn, buf, strlen(buf), 0);

    ...
}

在这段代码中,我们使用recv函数接收客户端发送的数据,然后使用send函数发送一段字符串给客户端。

  1. 关闭Socket

最后,在完成服务端的所有操作后,我们需要使用closesocket函数来关闭所有的Socket。代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    ...

    closesocket(sockSrv);
    closesocket(sockConn);
    WSACleanup();

    return 0;
}

三、示例说明

以上是实现TCP Socket客户端和服务端的详细步骤,下面我将通过两个示例代码来展示具体实现方法。

示例一:通过TCP Socket实现简单的聊天室

在这个示例中,我们通过TCP Socket实现一个简单的聊天室。代码如下:

//Server
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#include <iostream>

using namespace std;

int main()
{
    WSADATA wsadata;
    SOCKET sockSrv, sockConn;
    SOCKADDR_IN addrSrv, addrClient;

    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        return -1;
    }

    sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockSrv < 0)
    {
        return -1;
    }

    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    addrSrv.sin_addr.s_addr = INADDR_ANY;

    if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
    {
        return -1;
    }

    if (listen(sockSrv, 10) < 0)
    {
        return -1;
    }

    int len = sizeof(SOCKADDR);

    cout << "Server is listening..." << endl;

    sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
    cout << "A client connected!" << endl;

    while (1)
    {
        char recvBuf[100];
        int len = recv(sockConn, recvBuf, 100, 0);

        if (len <= 0)
        {
            break;
        }

        recvBuf[len] = '\0';
        cout << "Client: " << recvBuf << endl;

        char buf[100];
        cin >> buf;

        send(sockConn, buf, strlen(buf), 0);
    }

    closesocket(sockSrv);
    closesocket(sockConn);
    WSACleanup();

    return 0;
}


//Client
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#include <iostream>

using namespace std;

int main()
{
    WSADATA wsadata;
    SOCKET sockClient;
    SOCKADDR_IN addrSrv;

    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        return -1;
    }

    sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockClient < 0)
    {
        return -1;
    }

    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
    {
        return -1;
    }
    cout << "Connected to server!" << endl;

    while (1)
    {
        char buf[100];
        cin >> buf;

        send(sockClient, buf, strlen(buf), 0);

        char recvBuf[100];
        int len = recv(sockClient, recvBuf, 100, 0);
        recvBuf[len] = '\0';

        cout << "Server: " << recvBuf << endl;
    }

    closesocket(sockClient);
    WSACleanup();

    return 0;
}

在这个聊天室示例中,我们首先编写了一个服务端程序,用于监听连接请求。在客户端连接成功后,服务端会开始运行一个循环,等待客户端发送消息。当服务端接收到消息时,它会输出客户端发送的消息,并等待输入下一条消息发送给客户端。

客户端程序会首先连接到服务端,然后进入一个循环,等待用户输入消息。当用户输入一条消息时,客户端会将它发送给服务端,并等待服务端发送消息。客户端接收到服务端的消息后,会将该消息输出到屏幕上。

示例二:通过TCP Socket进行文件传输

在这个示例中,我们将使用TCP Socket实现简单的文件传输。将一个本地文件传输到远程机器上。该示例将演示文件的发送和接收过程。

服务端代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    WSADATA wsadata;
    SOCKET sockSrv, sockConn;
    SOCKADDR_IN addrSrv;

    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        return -1;
    }

    sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockSrv < 0)
    {
        return -1;
    }

    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    addrSrv.sin_addr.s_addr = INADDR_ANY;

    if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
    {
        return -1;
    }

    if (listen(sockSrv, 10) < 0)
    {
        return -1;
    }

    int len = sizeof(SOCKADDR);
    sockConn = accept(sockSrv, NULL, NULL);

    FILE* file = fopen("test.txt", "rb");
    char buf[1024];

    while (1)
    {
        int len = fread(buf, 1, 1024, file);

        if (len <= 0)
        {
            break;
        }

        send(sockConn, buf, len, 0);
    }

    fclose(file);

    closesocket(sockSrv);
    closesocket(sockConn);
    WSACleanup();

    return 0;
}

客户端代码如下:

#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
    WSADATA wsadata;
    SOCKET sockClient;
    SOCKADDR_IN addrSrv;

    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        return -1;
    }

    sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockClient < 0)
    {
        return -1;
    }

    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
    {
        return -1;
    }

    FILE* file = fopen("test_recv.txt", "wb");
    char buf[1024];

    while (1)
    {
        int len = recv(sockClient, buf, 1024, 0);

        if (len <= 0)
        {
            break;
        }

        fwrite(buf, 1, len, file);
    }

    fclose(file);

    closesocket(sockClient);
    WSACleanup();

    return 0;
}

本示例中,服务端首先通过文件流打开一个名为“test.txt”的本地文件,并每次读取1024字节的数据发送给客户端。客户端在接收到数据后,将接收到的数据写入到一个名为“test_recv.txt”的本地文件中。在完成数据传输后,服务端和客户端都会关闭连接和socket。

以上就是通过VC++实现TCP Socket客户端和服务端所需要遵循的流程及代码示例说明,希望对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vc++实现的tcp socket客户端和服务端示例 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Go学习笔记之map的声明和初始化

    下面是关于“Go学习笔记之map的声明和初始化”的详细讲解攻略。 标题 Go学习笔记之map的声明和初始化 简介 Go语言中的map是一种关联数组类型,可以将一个键映射到一个值。在使用map前需要进行声明和初始化操作。本文将详细讲解map的声明和初始化方法。 正文 map的声明 在Go语言中,可以通过make()函数来创建map。语法如下: mapName …

    other 2023年6月20日
    00
  • msixbundle怎么打开?win10后缀.MSIX安装包怎么安装使用?

    MSIXBundle的打开和安装使用攻略 MSIXBundle是一种用于打包和分发Windows应用程序的文件格式。它可以包含一个或多个MSIX安装包,以及其他相关资源。下面是详细的攻略,教你如何打开和安装使用MSIXBundle文件。 打开MSIXBundle文件 要打开MSIXBundle文件,按照以下步骤进行操作: 首先,确保你的计算机上已经安装了Wi…

    other 2023年8月5日
    00
  • Win11切换大小写有弹窗提示怎么取消?

    要取消Win11切换大小写时的弹窗提示,您可以按照以下步骤进行操作: 首先,打开Win11的设置菜单。您可以通过点击任务栏上的“开始”按钮,然后点击设置图标来打开设置菜单。 在设置菜单中,点击“个性化”选项。 在个性化选项中,选择“任务栏”选项。 在任务栏选项中,找到“通知区域”一栏,然后点击“选择哪些图标显示在任务栏上”。 在弹出的窗口中,找到“输入法”一…

    other 2023年8月16日
    00
  • Java 爬虫数据异步加载如何解决

    Java爬虫在处理数据时,如果遇到异步加载的情况,可能会导致数据获取不完整或者获取失败的问题。下面我将详细讲解Java爬虫如何解决异步加载数据的问题。 1. 了解网页异步加载的原理 网页异步加载是指在页面加载完成之后,通过JavaScript等技术异步向服务器请求数据,来达到实时更新页面内容的效果。这种异步加载的方式可以大大提高用户体验,但对于爬虫的数据获取…

    other 2023年6月25日
    00
  • 动态的样式语言less语法详解之变量与extend

    动态的样式语言Less语法详解之变量与Extend 1. 变量 在Less中,我们可以使用变量来存储和重用样式属性的值。变量可以包含任何类型的值,包括颜色、长度、字符串等。 定义变量 要定义一个变量,可以使用@符号,后面跟着变量的名称和值。例如: @primary-color: #ff0000; 使用变量 使用变量时,只需在属性值中使用@符号加上变量名称即可…

    other 2023年8月16日
    00
  • SQL Server 2008 数据库中创建只读用户的方法

    创建只读用户的方法有以下步骤: 创建登录名 首先需要创建一个登录名,该登录名用于让用户登录到SQL Server。创建登录名的步骤如下: USE master; GO CREATE LOGIN ReadOnlyUser WITH PASSWORD = ‘P@ssword123’; 其中,ReadOnlyUser是登录名的名称,P@ssword123是该用户的…

    other 2023年6月27日
    00
  • ubuntu下重启网络

    以下是关于“Ubuntu下重启网络”的完整攻略: 1. 使用systemd-resolved服务重启网络 Ubuntu 18.04及更高版本使用systemd-resolved服务来管理网络连接。您可以使用以下命令重启网络: sudo systemctl restart systemd-resolved.service 这将重启systemd-resolve…

    other 2023年5月6日
    00
  • 微信小程序实现循环嵌套数据选择

    type: Array, value: [], }, }, methods: { handleChange(e) { const { value } = e.detail; const selectedItem = this.data.data[value]; const { children } = selectedItem; if (children &…

    other 2023年7月27日
    00
合作推广
合作推广
分享本页
返回顶部