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

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日

相关文章

  • python–判断路径是否为目录或文件

    python–判断路径是否为目录或文件 在Python中,我们经常需要判断给定的路径是目录还是文件,以便根据不同的情况进行后续的操作。本文将介绍如何使用Python的内置模块来判断给定的路径是目录还是文件。 os模块 Python的内置模块os提供了很多文件和文件夹操作函数,其中包括判断路径是否为目录或文件的函数。 isdir() isdir()函数用于判…

    其他 2023年3月29日
    00
  • Android TCP 文件客户端与服务器DEMO介绍

    下面我将详细讲解“Android TCP 文件客户端与服务器DEMO介绍”的完整攻略。 Android TCP 文件客户端与服务器DEMO介绍 简介 本DEMO主要演示了Android TCP文件传输的基本原理和使用方法,分为客户端和服务器端两部分。客户端主要负责选择文件、建立TCP连接、发送文件数据等操作;服务器端主要负责接收连接、接收并保存文件数据等操作…

    other 2023年6月27日
    00
  • Android实现3D标签云简单效果

    Android实现3D标签云简单效果攻略 简介 在本攻略中,我们将学习如何在Android应用中实现一个简单的3D标签云效果。标签云是一种常见的数据可视化方式,通过不同大小和颜色的标签来展示数据的重要性和关联性。 步骤 步骤一:导入依赖库 首先,我们需要在项目的build.gradle文件中添加以下依赖库: dependencies { implementa…

    other 2023年8月25日
    00
  • win7升级win10更新到99%蓝屏重启该怎么办?

    如果在升级Win7到Win10的过程中,系统更新到99%时出现蓝屏重启的情况,你可以尝试以下步骤解决问题: 1. 检查硬件兼容性 首先需要检查电脑硬件是否满足Win10的最低要求,因为不是所有的电脑都可以升级到Win10。如果硬件满足要求,则可以尝试重新进行升级。 2. 使用Windows 10安装媒介升级 可以尝试使用Windows 10官方安装媒介进行升…

    other 2023年6月27日
    00
  • Android控件系列之CheckBox使用介绍

    Android控件系列之CheckBox使用介绍 什么是CheckBox控件? CheckBox控件是一个可以被选中或取消选中的复选框控件,常用于表示某些选项的状态。CheckBox通常与TextView或者Button等控件一起使用,用于辅助用户进行操作。 CheckBox控件的使用步骤 步骤1:在xml布局中添加CheckBox控件 在xml布局文件中使…

    other 2023年6月27日
    00
  • 关于maven:播放框架2.3.8 找不到org.apache.poi依赖项

    以下是关于“关于maven:播放框架2.3.8找不到org.apache.poi依赖项”的完整攻略,包含两个示例。 关于Maven: 播放框架2.3.8找不到org.apache.poi依赖项 在使用Maven构建Java项目时,有时会出现找不到依赖项的情况。以下是关于如何解决播放框架2.3.8找不到org.apache.poi依赖项的详细攻略。 1. 检查…

    other 2023年5月9日
    00
  • win10临时文件夹移动到c盘根目录下怎么操作?临时文件夹移动到c盘教程

    下面是详细的操作攻略,我分别给出了Windows 10系统自带的方法和通过第三方软件进行操作的方法。 方法一:使用Windows自带的设置功能 打开“Windows设置”菜单,通过键盘快捷键 “Win+I” 实现 在“Windows设置”窗口中选择“系统”,然后选择“存储” 在“存储”菜单下方找到“更多存储设置”,点击进入 在更多存储设置页面下,找到“临时文…

    other 2023年6月27日
    00
  • iOS应用开发中视图控件UIWindow的基本使用教程

    iOS应用开发中视图控件UIWindow的基本使用教程 1.什么是UIWindow 在iOS应用中,UIWindow是所有视图的容器,它是应用中最高级的视图。一般情况下,应用中只有一个UIWindow,而且这个UIWindow充满整个屏幕,我们可以把它看成是应用程序的“主窗口”。 2.UIWindow的基本用法 2.1 创建UIWindow 创建UIWind…

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