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日

相关文章

  • IOS开发之手势响应事件优先级的实例详解

    IOS开发之手势响应事件优先级的实例详解 1. 理解手势识别器的优先级 在IOS开发中,手势识别器(Gesture Recognizer)是用来识别和处理用户的手势操作的工具。当多个手势同时发生在某个视图上时,系统需要判断哪个手势应该被识别为有效手势。这个判断的过程就是手势识别器的优先级问题。 手势识别器的优先级是按照一个预定义的优先级顺序进行判断的,默认情…

    other 2023年6月28日
    00
  • C语言超详细讲解数据结构中双向带头循环链表

    C语言超详细讲解数据结构中双向带头循环链表 什么是双向带头循环链表 双向带头循环链表是一种非常常用的数据结构,它由多个节点组成,每个节点都有一个前驱指针和一个后继指针,形成一个双向链表;同时,它也是循环链表,即链表的头指针和尾指针是相连的形成一个环的结构;而带头链表则是在链表的开头添加一个头节点来方便书写,方便读者理解,常见于书籍和教程中。 因此,双向带头循…

    other 2023年6月27日
    00
  • cd命令进入d盘文件夹

    如何使用cd命令进入D盘文件夹 在Windows操作系统中,使用cd命令可以进入指定的文件夹。下面是详细的攻略,包括两个示例说明。 1. 打开命令提示符 在Windows操作系统中,可以通过按下Win+R键,然后输入cmd并按下回车键来打开命令提示符。 2. 进入D盘 在命令提示符中,输入以下命令: D: 这个命令表示要进入D盘。 3. 进入文件夹 如果要进…

    other 2023年5月7日
    00
  • Python3简单的输入输出及内置函数查看

    Python3简单的输入输出及内置函数查看 Python3是一种高级编程语言,其语法简单易懂,入门门槛低,且广泛应用于各种领域的开发。在Python3中,处理数据进出大多以输入输出(I/O)和内置函数为核心。因此,本篇文章将会介绍Python3中简单的输入输出及内置函数查看。 输入输出 Python3中,有以下几种基本的输入输出方式: 1. 输出 输出是将结…

    其他 2023年3月28日
    00
  • C++中默认无参构造函数的工作机制浅析

    C++中默认无参构造函数的工作机制浅析 什么是默认无参构造函数? 在C++中,如果我们声明一个类却没有为其定义构造函数(无论是无参构造函数还是有参构造函数),编译器会自动为该类创建一个默认构造函数。默认构造函数是一种无参构造函数,用于创建该类的对象时不需要任何实参传入。 默认无参构造函数的工作机制 默认无参构造函数的工作机制是在对象创建时自动调用,用于对成员…

    other 2023年6月26日
    00
  • Dreamweaver CS3网页制作中的CSS布局规则

    Dreamweaver CS3网页制作中的CSS布局规则攻略 1. CSS布局规则简介 在Dreamweaver CS3中,CSS布局规则用于控制网页元素的位置和样式。通过使用CSS布局规则,您可以创建具有各种布局风格的网页。 2. CSS布局规则的基本语法 CSS布局规则由选择器和声明块组成。选择器用于选择要应用布局规则的HTML元素,声明块包含一系列属性…

    other 2023年9月5日
    00
  • 如何让32位Win7完美使用4G内存的方法介绍

    如何让32位Win7完美使用4G内存的方法介绍 由于32位的Windows 7操作系统默认只能使用3.2GB的内存,如果你想让它完美地使用4GB内存,你可以按照以下步骤进行设置。 步骤一:检查操作系统版本 首先,确保你的Windows 7是32位版本。你可以通过以下步骤来检查: 点击开始菜单,选择“计算机”。 右键点击“计算机”,选择“属性”。 在“系统”窗…

    other 2023年7月28日
    00
  • React Fiber 链表操作及原理示例详解

    React Fiber 是 React 16 中全新的协调引擎,它可以在不阻塞渲染主线程的情况下,执行异步任务。为了实现这一目标,React Fiber 使用链表数据结构来管理组件树的遍历及操作。 React Fiber 的链表包含两个主要的节点类型:FiberNode 和 EffectNode。FiberNode 用于表示当前的组件,而 EffectNod…

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