网络编程(TCP和UDP的基础模型)

一、TCP基础模型:

 tcp Ser:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <head.h>

#define PORT 8888             //1024~49151
#define IP "192.168.122.109" //ifconfig查看本机IP

int main(int argc, const char *argv[])
{
    //创建流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("sfd = %d\n", sfd);
                                                                           
    //设置允许端口被快速复用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允许端口快速重用成功\n");


    //填充地址信息结构体,真实的地址信息结构体根据地址族指定
    //AF_INET: man 7 ip
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;      //必须填AF_INET
    sin.sin_port        = htons(PORT);  //端口号:1024~49151
    sin.sin_addr.s_addr = inet_addr(IP); //本机IP ifconfig查看

    //绑定服务器的IP和端口--->必须绑定
    if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind success \n");

    //将套接字设置为被动监听状态
    if(listen(sfd, 128) < 0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("listen success\n");

    struct sockaddr_in cin;     //存储客户端的地址信息
    socklen_t addrlen = sizeof(cin);

    //从已完成连接的队列中获取一个客户端信息,生成一个新的文件描述符
    //该文件描述符才是与客户端通信的文件描述符
    //int newfd = accept(sfd, NULL, NULL);
    int newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
    if(newfd < 0)
    {
        ERR_MSG("accept");
        return -1;
    }
    printf("[%s : %d] newfd=%d 客户端连接成功\n", \
            inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);

    char buf[128] = "";
    ssize_t res = 0;
    while(1)
    {
        bzero(buf, sizeof(buf));
        //接收数据
        res = recv(newfd, buf, sizeof(buf), 0);
        if(res < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0 == res)
        {
            printf("[%s : %d] newfd=%d 客户端下线\n", \
                    inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
            break;
        }

        printf("[%s : %d] newfd=%d : %s\n", \
                inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, buf);

        //发送数据
        strcat(buf, "*_*");
        if(send(newfd, buf, sizeof(buf), 0) < 0)
        {
            ERR_MSG("send");
            return -1;
        }
        printf("send success\n");
    }

    //关闭所有文件描述符
    close(newfd);
    close(sfd);

    return 0;
}

tcp Cli: 

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>                                                                
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <head.h>

#define PORT 8888             //端口号: 填服务器绑定端口号
#define IP "192.168.122.109" //IP地址:服务器绑定的IP地址

int main(int argc, const char *argv[])
{
    //创建流式套接字
    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("cfd = %d\n", cfd);

    //绑定客户端的的IP和端口--->非必须绑定
    //若不绑定,则操作系统会给客户端绑定上客户端所在的主机IP,以及随机端口(49152~65535)


    //填充服务器的地址信息结构体,真实的地址信息结构体根据地址族指定
    //AF_INET: man 7 ip 
    //要连接哪个服务器,就填对应服务器的IP和端口
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;      //必须填AF_INET
    sin.sin_port        = htons(PORT);  //端口号: 填服务器绑定端口号
    sin.sin_addr.s_addr = inet_addr(IP); //IP地址:服务器绑定的IP地址

    //连接服务器
    if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        ERR_MSG("connect");
        return -1;
    }
    printf("connect success\n");

    char buf[128] = "";
    ssize_t res = 0;
    while(1)
    {
        bzero(buf, sizeof(buf));
        printf("请输入>>> ");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = 0;

        //发送数据
        if(send(cfd, buf, sizeof(buf), 0) < 0)
        {
            ERR_MSG("send");
            return -1;
        }
        printf("send success\n");

        bzero(buf, sizeof(buf));
        //接收数据
        res = recv(cfd, buf, sizeof(buf), 0);
        if(res < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0 == res)
        {
            printf("[%s : %d] cfd=%d 服务器掉线\n", IP, PORT, cfd);
            break;
        }

        printf("[%s : %d] cfd=%d : %s\n", IP, PORT, cfd, buf);
    }

    //关闭所有文件描述符
    close(cfd);

    return 0;
}

二、UDP基础模型:

udp Ser:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <head.h>

#define PORT 6666               //端口号:1024~49151
#define IP "192.168.122.109"    //本机IP:ifconfig                                      


int main(int argc, const char *argv[])
{
    //创建报式套接字
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("sfd = %d\n", sfd);

    //填充服务器自身的地址信息结构体,真实的地址信息结构体根据地址族指定
    //AF_INET : man 7 ip
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;      //必须填AF_INET
    sin.sin_port        = htons(PORT);      //端口号:1024~49151
    sin.sin_addr.s_addr = inet_addr(IP);    //本机IP:ifconfig


    //绑定服务器的地址信息结构体到套接字上
    if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind success\n");

    char buf[128] = "";
    ssize_t res = 0;
    struct sockaddr_in cin;     //存储接收到的数据包从哪里来
    socklen_t addrlen = sizeof(cin);

    while(1)
    {
        bzero(buf, sizeof(buf));
        //接收数据
        res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen);
        //res = recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL);
        //res = recv(sfd, buf, sizeof(buf), 0);
        //res = read(sfd, buf, sizeof(buf));
        if(res < 0)
        {
            ERR_MSG("recvfrom");
            return -1;
        }
        printf("[%s : %d] : %s\n", \
                inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);

        strcat(buf, "*_*");
        //发送数据
        if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin,  sizeof(cin)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        printf("sendto success\n");
    }

    //关闭文件描述符
    close(sfd);


    return 0;
}

 udp Cli:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <head.h>

#define PORT 6666               //端口号:服务器绑定的端口号
#define IP "192.168.122.109"    //IP:服务器绑定的IP


int main(int argc, const char *argv[])
{
    //创建报式套接字
    int cfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(cfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("cfd = %d\n", cfd);



    //绑定客户端的地址信息结构体到套接字上---->非必须绑定
    //若不绑定,则操作系统会给客户端绑定运行主机的IP和随机端口

    //填充服务器的地址信息结构体,给sendto函数使用
    //要发给谁,就填谁的地址信息
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;      //必须填AF_INET
    sin.sin_port        = htons(PORT);      //端口号:服务器绑定的端口号
    sin.sin_addr.s_addr = inet_addr(IP);    //IP:服务器绑定的IP


    char buf[128] = "";
    ssize_t res = 0;
    struct sockaddr_in rcvaddr;     //存储接收到的数据包从哪里来
    socklen_t addrlen = sizeof(rcvaddr);

    while(1)
    {
        bzero(buf, sizeof(buf));
        printf("请输入>>> ");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = 0;

        //发送数据
        if(sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin,  sizeof(sin)) < 0)
        {                                                                                
            ERR_MSG("sendto");
            return -1;
        }
        printf("sendto success\n");

        //接收数据
        res = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&rcvaddr, &addrlen);
        //res = recvfrom(cfd, buf, sizeof(buf), 0, NULL, NULL);
        //res = recv(cfd, buf, sizeof(buf), 0);
        //res = read(cfd, buf, sizeof(buf));
        if(res < 0)
        {
            ERR_MSG("recvfrom");
            return -1;
        }
        printf("[%s : %d] : %s\n", \
                inet_ntoa(rcvaddr.sin_addr), ntohs(rcvaddr.sin_port), buf);

    }

    //关闭文件描述符
    close(cfd);


    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/82906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无涯教程-Perl - wait函数

描述 该函数等待子进程终止,返回已故进程的进程ID。进程的退出状态包含在$?中。 语法 以下是此函数的简单语法- wait返回值 如果没有子进程,则此函数返回-1,否则将显示已故进程的进程ID Perl 中的 wait函数 - 无涯教程网无涯教程网提供描述该函数等待子进程终止,返回已故…

Java 项目日志实例:LogBack

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ LogBack 和 Log4j 都是开源日记工具库&#xff0c;LogBack 是 Log4j 的改良版本&#xff0c;比 Log4j 拥有更多的特性&#xff0c;同时也带来很大性能提升。LogBack 官方建…

Pytorch建立MyDataLoader过程详解

简介 torch.utils.data.DataLoader(dataset, batch_size1, shuffleNone, samplerNone, batch_samplerNone, num_workers0, collate_fnNone, pin_memoryFalse, drop_lastFalse, timeout0, worker_init_fnNone, multiprocessing_contextNone, generatorNone, *, prefetch_factorN…

TensorFlow2.1 模型训练使用

文章目录 1、环境安装搭建2、神经网络2.1、解决线性问题2.2、FAshion MNIST数据集使用 3、卷积神经网络3.1、卷积神经网络使用3.2、ImageDataGenerator使用3.3、猫狗识别案例3.4、参数优化 3.5、石头剪刀布案例4、词条化4.1、讽刺数据集的词条化和序列化4.2、词嵌入 1、环境安装…

[保研/考研机试] KY11 二叉树遍历 清华大学复试上机题 C++实现

题目链接&#xff1a; 二叉树遍历_牛客题霸_牛客网编一个程序&#xff0c;读入用户输入的一串先序遍历字符串&#xff0c;根据此字符串建立一个二叉树&#xff08;以指针方式存储&#xff09;。题目来自【牛客题霸】https://www.nowcoder.com/share/jump/43719512169254700747…

实数信号的傅里叶级数研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

(2)、将SpringCache扩展功能封装为starter

(2)、将SpringCache扩展功能封装为starter 1、准备工作 前面我们写了一个common-cache模块,尽可能的将自定义的RedisConnectionFactory, RedisTemplate, RedisCacheManager等Bean封装了起来。 就是为了方便我们将其封装为一个Starter。 我们这里直接《SpringCache+Redis实…

微信个人号开发,实现机器人辅助社群操作

微信 iPad 协议是指用于在 iPad 设备上使用微信应用的技术协议。一般来说&#xff0c;通过该协议可以将微信账号同步到 iPad 设备上&#xff0c;并且可以在 iPad 上发送和接收微信消息&#xff0c;查看好友列表、聊天记录等功能。微信 iPad 协议是通过私有API实现的。 需要一定…

嵌入式:ARM Day6

作业:完成cortex-A7核UART总线实验 目的&#xff1a;1.输入a,显示b&#xff0c;将输入的字符的ASCII码下一位字符输出 2.原样输出输入的字符串 源码&#xff1a; uart4.h #ifndef __UART4_H__ #define __UART4_H__#include "stm32mp1xx_rcc.h" #incl…

九、Linux下,如何在命令行进入文本编辑页面?

1、文本编辑基础 说到文本编辑页面&#xff0c;那就必须提到vi和vim&#xff0c;两者都是Linux系统中&#xff0c;常用的文本编辑器 2、三种工作模式 3、使用方法 &#xff08;1&#xff09;在进入Linux系统&#xff0c;在输入vim text.txt之后&#xff0c;会进入文本编辑中&…

Python多组数据三维绘图系统

文章目录 增添和删除坐标数据更改绘图逻辑源代码 Python绘图系统&#xff1a; 基础&#xff1a;将matplotlib嵌入到tkinter &#x1f4c8;简单的绘图系统 &#x1f4c8;数据导入&#x1f4c8;三维绘图系统自定义控件&#xff1a;坐标设置控件&#x1f4c9;坐标列表控件 增添和…

【力扣】84. 柱状图中最大的矩形 <模拟、双指针、单调栈>

目录 【力扣】84. 柱状图中最大的矩形题解暴力求解双指针单调栈 【力扣】84. 柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例…

使用ChatGPT进行创意写作的缺点

Open AI警告ChatGPT的使用者要明白此工具的局限性&#xff0c;更不应完全依赖。作为一位创作者&#xff0c;这一点非常重要&#xff0c;应尽可能地避免让版权问题或不必要的文体问题出现在自己的作品中。[1] 毕竟使用ChatGPT进行创意写作目前还有以下种种局限或缺点[2]&#xf…

5.5.webrtc的线程管理

今天呢&#xff0c;我们来介绍一下线程的管理与绑定&#xff0c;首先我们来看一下web rtc中的线程管理类&#xff0c;也就是thread manager。对于这个类来说呢&#xff0c;其实实现非常简单&#xff0c;对吧&#xff1f; 包括了几个重要的成员&#xff0c;第一个成员呢就是ins…

学习笔记230804---逻辑跳转this.$router.push在写法上的优化

今天和资深前端代码写重&#xff0c;同时写页面带参跳转&#xff0c;组长觉得他写的方式比我高端一点&#xff0c;我觉得确实是&#xff0c;像资深大佬学习。 我的写法&#xff1a; this.$router.push(/bdesign?applicationId${this.data.id}&appName${this.data.name})…

[VS/C++]如何更好的配置DLL项目中的成品输出

注意&#xff0c;解决方案与项目不放在同一个文件夹中&#xff0c;即不选中图中选项 直入主题 首先右键项目选择属性&#xff0c;或者选中项目然后AltEnter 选择配置属性下的常规 分别在四种配置中编辑输出目录如下 注意&#xff0c;四种配置要分别配置&#xff0c;一个个来…

一百六十一、Kettle——Linux上安装的kettle9.2开启carte服务(亲测、附流程截图)

一、目的 在Linux上安装好kettle9.2并且连接好各个数据库后&#xff0c;下面开启carte服务 二、实施步骤 &#xff08;一&#xff09;carte服务文件路径 kettle的Linux运行的carte服务文件是carte.sh &#xff08;二&#xff09;修改kettle安装路径下的pwd文件夹里的服务器…

Netty+springboot开发即时通讯系统笔记(四)终

实时性 1.线程池多线程&#xff0c;把消息同步给其他端和对方用户&#xff0c;其中数据持久化往往是最浪费时间的操作&#xff0c;可以使用mq异步存储&#xff0c;因为其他业务不需要拿着整条数据&#xff0c;只需要这条数据的id进行操作。 2。消息校验前置&#xff0c;放在t…

谷歌推出首款量子弹性 FIDO2 安全密钥

谷歌在本周二宣布推出首个量子弹性 FIDO2 安全密钥&#xff0c;作为其 OpenSK 安全密钥计划的一部分。 Elie Bursztein和Fabian Kaczmarczyck表示&#xff1a;这一开源硬件优化的实现采用了一种新颖的ECC/Dilithium混合签名模式&#xff0c;它结合了ECC抵御标准攻击的安全性和…

机器学习与模式识别3(线性回归与逻辑回归)

一、线性回归与逻辑回归简介 线性回归主要功能是拟合数据&#xff0c;常用平方误差函数。 逻辑回归主要功能是区分数据&#xff0c;找到决策边界&#xff0c;常用交叉熵。 二、线性回归与逻辑回归的实现 1.线性回归 利用回归方程对一个或多个特征值和目标值之间的关系进行建模…