C++利用Socket实现主机间的UDP/TCP通信

yizhihongxing

C++利用Socket实现主机间的UDP/TCP通信攻略

什么是Socket?

在计算机网络中,Socket又被称为“套接字”,是计算机之间通信的一种抽象,它是TCP/IP协议族中API的一部分,是支持TCP/IP协议的网络通信的基本操作单元,可以通过Socket在两台计算机之间建立连接,进行数据传输。

实现主机间的UDP通信

1. 创建一个UDP套接字

在C++中,采用socket函数创建socket套接字,其中domain代表协议族,type为套接字类型(传输控制协议TCP或用户数据报协议UDP),protocol指定协议编号。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>

using namespace std;

int main() {
    int sockfd;
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        cerr << "Can't create a UDP socket." << endl;
        return 0;
    }
    return 0;
}

2. 绑定套接字

bind函数将一个socket与一个IP地址和端口号进行绑定。

struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(8888);

if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
    cerr << "Can't bind." << endl;
    return 0;
}

3. 接收和发送数据包

使用recvfrom函数接收数据包,使用sendto函数发送数据包。

char buf[1024];
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
memset(&clientaddr, 0, sizeof(clientaddr));

while (true) {
    memset(buf, 0, sizeof(buf));
    if (recvfrom(sockfd, buf, sizeof(buf), 0, 
            (struct sockaddr *)&clientaddr, &clientlen) < 0) {
        cerr << "Can't receive datagram." << endl;
    }

    cout << "Received: ";
    cout.write(buf, strlen(buf));
    cout << endl;

    if (sendto(sockfd, buf, strlen(buf), 0, 
            (struct sockaddr *)&clientaddr, clientlen) < 0) {
        cerr << "Can't send datagram." << endl;
    }
}

实现主机间的TCP通信

1. 创建一个TCP套接字

创建TCP套接字与UDP套接字的步骤基本一致,只需要将第二个参数改为SOCK_STREAM即可。

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    cerr << "Can't create a TCP socket." << endl;
    return 0;
}

2. 绑定套接字并开始监听

与UDP不同,TCP需要先绑定套接字并开始监听。使用listen函数进行监听。

struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(8888);

if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
    cerr << "Can't bind." << endl;
    return 0;
}

if (listen(sockfd, 5) < 0) {
    cerr << "Can't listen." << endl;
    return 0;
}

3. 接受连接请求并发送数据

使用accept函数接受客户端的连接请求,使用send和recv函数进行数据的发送和接收。

int connfd;
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
memset(&clientaddr, 0, sizeof(clientaddr));

while (true) {
    if ((connfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientlen)) < 0) {
        cerr << "Can't accept." << endl;
        return 0;
    }

    char sendline[] = "Hello, world!\n";
    char recvline[1024];
    memset(recvline, 0, sizeof(recvline));

    if ((recv(connfd, recvline, sizeof(recvline), 0)) < 0) {
        cerr << "Can't receive." << endl;
        return 0;
    }

    cout << "Received: ";
    cout.write(recvline, strlen(recvline));
    cout << endl;

    if ((send(connfd, sendline, strlen(sendline), 0)) < 0) {
        cerr << "Can't send." << endl;
        return 0;
    }

    close(connfd);
}

示例1:使用Socket实现基本的UDP通信

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>

using namespace std;

int main() {
    int sockfd;
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        cerr << "Can't create a UDP socket." << endl;
        return 0;
    }

    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(8888);

    if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
        cerr << "Can't bind." << endl;
        return 0;
    }

    char buf[1024];
    struct sockaddr_in clientaddr;
    socklen_t clientlen = sizeof(clientaddr);
    memset(&clientaddr, 0, sizeof(clientaddr));

    while (true) {
        memset(buf, 0, sizeof(buf));
        if (recvfrom(sockfd, buf, sizeof(buf), 0, 
                (struct sockaddr *)&clientaddr, &clientlen) < 0) {
            cerr << "Can't receive datagram." << endl;
        }

        cout << "Received: ";
        cout.write(buf, strlen(buf));
        cout << endl;

        if (sendto(sockfd, buf, strlen(buf), 0, 
                (struct sockaddr *)&clientaddr, clientlen) < 0) {
            cerr << "Can't send datagram." << endl;
        }
    }

    close(sockfd);

    return 0;
}

示例2:使用Socket实现基本的TCP通信

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>

using namespace std;

int main() {
    int sockfd;
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        cerr << "Can't create a TCP socket." << endl;
        return 0;
    }

    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(8888);

    if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
        cerr << "Can't bind." << endl;
        return 0;
    }

    if (listen(sockfd, 5) < 0) {
        cerr << "Can't listen." << endl;
        return 0;
    }

    int connfd;
    struct sockaddr_in clientaddr;
    socklen_t clientlen = sizeof(clientaddr);
    memset(&clientaddr, 0, sizeof(clientaddr));

    while (true) {
        if ((connfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientlen)) < 0) {
            cerr << "Can't accept." << endl;
            return 0;
        }

        char sendline[] = "Hello, world!\n";
        char recvline[1024];
        memset(recvline, 0, sizeof(recvline));

        if ((recv(connfd, recvline, sizeof(recvline), 0)) < 0) {
            cerr << "Can't receive." << endl;
            return 0;
        }

        cout << "Received: ";
        cout.write(recvline, strlen(recvline));
        cout << endl;

        if ((send(connfd, sendline, strlen(sendline), 0)) < 0) {
            cerr << "Can't send." << endl;
            return 0;
        }

        close(connfd);
    }

    return 0;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++利用Socket实现主机间的UDP/TCP通信 - Python技术站

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

相关文章

  • centos软链接命令(十)

    CentOS软链接命令(十) 在Linux系统中,软链接(Symbolic Link)也称为符号链接,是一种特殊的文件类型,它是一个指向另一个文件的快捷方式。软链接可以帮助我们在不更改原文件的情况下,访问另一个文件。CentOS是一种常用的Linux操作系统,它提供了许多常用的软链接命令。本文将介绍CentOS中常用的软链接命令。 创建软链接 我们可以使用l…

    其他 2023年3月28日
    00
  • pythondataframe筛选列表的值转为list【常用】

    pythondataframe筛选列表的值转为list【常用】 在Python中,使用Pandas库可以进行数据框DataFrame操作。有时我们需要从DataFrame中筛选出符合某些条件的数据,并将这些数据转为一个列表,方便后续的处理。本文将演示如何使用Pandas来实现这个功能。 数据准备 我们先定义一个简单的DataFrame,包含商品名称、单价和库…

    其他 2023年3月28日
    00
  • Go 日志封装实战示例详解

    下面我来详细讲解“Go 日志封装实战示例详解”的完整攻略。 什么是日志封装? 日志是我们开发过程中一个非常重要的组成部分,在出现故障或错误时能够提供非常宝贵的信息。封装日志的意思是使日志系统更易于使用、管理和扩展。比如,我们可以将日志信息打印到文件、控制台以及网络中,同时也可以将级别划分为不同的等级,方便我们对日志进行过滤、分类和统计。 在 Go 中,标准库…

    other 2023年6月25日
    00
  • 关于c#:无法添加对.dll的引用。请确保该文件可访问 并且…

    关于C#:无法添加对.dll的引用攻略 在C#中,我们可以使用引用来使用其他程序集中的类和方法。有时,我们可能会遇到无法添加对.dll的引用的问题。本攻略将介绍这个问题的原因,并提供两个示例。 原因 无法添加对.dll的引用的原因可能有多。以下是一些常见的原因: 文件不可访问:.dll文件可能被其他进程锁定,或者我们没有足够的权限来访问文件。 文件已损坏:.…

    other 2023年5月9日
    00
  • JS中作用域以及变量范围分析

    JS中作用域以及变量范围分析 在JavaScript中,作用域是指变量、函数和对象的可访问性和可见性的范围。了解作用域和变量范围对于编写高效、可维护的代码至关重要。本攻略将详细讲解JS中的作用域以及变量范围分析。 1. 作用域类型 在JS中,有两种主要的作用域类型:全局作用域和局部作用域。 全局作用域 全局作用域是在整个JS程序中都可访问的作用域。在全局作用…

    other 2023年7月29日
    00
  • 借贷宝人脸识别失败怎么办 借贷宝人脸识别失败解决方法

    借贷宝人脸识别失败怎么办 什么是借贷宝人脸识别? 借贷宝是一家互联网金融公司,提供在线借贷服务。为了防止身份欺诈,借贷宝使用了人脸识别技术,在用户注册和借款申请等环节中要求用户完成人脸识别操作。 借贷宝人脸识别失败的原因 借贷宝人脸识别失败的原因有很多,包括拍摄光线不足、图像模糊、佩戴眼镜或口罩、用户上传的照片不符合要求等。 借贷宝人脸识别失败的解决方法 如…

    other 2023年6月27日
    00
  • LINUX安全运维之:文件系统的权限修改与安全设置

    LINUX安全运维之:文件系统的权限修改与安全设置 一、权限基础知识 为了保护系统安全,Linux文件系统采用了访问权限的方式控制对文件和文件夹的读写操作。Linux文件的权限信息包含了三个部分: 用户权限:可访问文件的用户或用户组。分别被分为文件属主(owner)、所在组(group)以及其他人(other)。 文件权限:包括读、写、执行三类权限。 特殊权…

    other 2023年6月27日
    00
  • javascriptdom编程艺术

    JavaScript DOM编程艺术是一本介绍如何使用JavaScript操作HTML和CSS的经典书籍。以下是使用JavaScript DOM编程艺术的完整攻略: 首先,创建一个HTML文档,并在其中添加一些元素。例如,可以创建一个包含一个按钮和一个文本框的HTML文档: “`html JavaScript DOM Programming Submit …

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