首页 > 系统相关 >linux C++ UDP

linux C++ UDP

时间:2023-09-02 17:11:27浏览次数:51  
标签:serv UDP addr sock C++ linux message include

1. UDP与TCP差异:

注意:UDP不同于TCP,没有请求连接过程connect()与受理过程accpet(),因此无法区分客户端与服务器端。

TCP与UDP差异仅仅在于TCP存在在不可靠IP层的流控制机制,所以TCP可以提供可靠数据服务,形象化的比喻就是TCP相当于打电话,而UDP相当于信封,

电话得先建立一个可靠的信道,再进行数据传输,UDP是我要将信放入信封之中,发给那个人,至于那个人是否存在,能否接受,都是不可控制的,

也就是说邮寄过程是一种不可靠的数据传递方式,有可能会出现丢包问题。

1.1 TCP比UDP慢的原因:

 

2. UDP内部工作原理:

来源:《TCP&IP网络编程》P102

3. UDP客户端套接字的地址分配

 

4. 基于UDP的数据I/O函数

 

5. 实现UDP回声客户端/服务端

UDP 回声客户端实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>

#define BUFF_SZIE 1024

void handling_error(char * message);

int main(int argc ,char * argv[]){

    int sock;
    char message[BUFF_SZIE];
    int str_len;
    socklen_t addr_size;

    struct sockaddr_in serv_addr,from_addr;

    if(argc != 3){
        printf("Usage : %s <IP> <port> \n",argv[0]);
    }

    sock = socket(PF_INET,SOCK_DGRAM,0);

    if(sock == -1){
        handling_error((char *)"socket() error!");
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    serv_addr.sin_port = htons(atoi(argv[2]));

    while(1){

        fputs("Insert message (q to quit):",stdout);
        fgets(message,sizeof(message),stdin);
        if(!strcmp(message,"q\n") || !strcmp(message,"Q\n")){
            break;
        }

        sendto(sock,message,strlen(message),0,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
        addr_size = sizeof(from_addr);
        str_len = recvfrom(sock,message,BUFF_SZIE,0,(struct sockaddr *)&from_addr,&addr_size);
        message[str_len] = 0;
        printf("Message from server : %s",message);

        printf("\n");                                                                           //下面三行代码就是输出接受哪个服务端,他的IP,端口号是多少
        printf("IP : %s\n",inet_ntoa (from_addr.sin_addr));
        printf("Port : %d\n",ntohs(from_addr.sin_port));

    }
    close(sock);


    return 0;
}

void handling_error(char * message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}
UDP 回声服务端实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>

#define BUFF_SZIE 1024

void handling_error(char * messaage);

int main(int argc ,char * argv[]){

    int serv_sock;
    char messgae[BUFF_SZIE];
    int str_len;
    socklen_t clent_addr_size;

    struct sockaddr_in serv_addr,client_addr;

    if(argc != 2){
        printf("Usage %s <port>\n",argv[0]);
    }

    serv_sock = socket(PF_INET,SOCK_DGRAM,0);
    if(serv_sock == -1){
        printf("socket() error!");
    }

    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(atoi(argv[1]));

    if(bind(serv_sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1){
        handling_error((char *)"bind() error!");
    }

    while(1){
        clent_addr_size = sizeof(client_addr);
        str_len = recvfrom(serv_sock,messgae,BUFF_SZIE,0,(struct sockaddr *)&client_addr,&clent_addr_size);
        sendto(serv_sock,messgae,str_len,0,(struct sockaddr *)&client_addr,clent_addr_size);

        printf("\n");                                                                                       //下面三行代码就是输出发送给哪个客户端,他的IP,端口号是多少
        printf("IP : %s\n",inet_ntoa (client_addr.sin_addr));
        printf("Port : %d\n",ntohs(client_addr.sin_port));
    }

    close(serv_sock);
    
    return 0;
}

void handling_error(char * message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

 

标签:serv,UDP,addr,sock,C++,linux,message,include
From: https://www.cnblogs.com/chenruiwe/p/17673746.html

相关文章

  • c++编译
    1.1c++编译c++脚本程序写完之后,并不能直接运行,需要进行编译,转成.o文件,再链接才能运行,一般包括:预处理,汇编,编译。链接四步,如下:预编译把.c源文件编译成.ii预处理文件gcc-E[源文件.c]-o[自定义名.ii]编译成汇编语言把.i文件编译成.s汇编语言文件gcc-S[......
  • C++程序的内存模型--模型四区
      C++中在程序运行前分为全局区和代码区 代码区特点是共享和只读 全局区中存放全局变量、静态变量、常量 常量区中存放const修饰的全局变量和字符串常量 //栈区//由编译器自动分配释放、存放函数的参数值、局部变量等//注意:不要返回局部变量的地址,栈区开辟的数据由编译器......
  • linux开发C/C++
    最近在部署项目的时候总是会遇到关于C++的编译问题,由于之前学习C++只是为了参加算法竞赛,缺少这一部分的知识,所以学习一下这一相关内容,并做一下记录参考:VSCode开发C++七讲【基于VSCode和CMake实现C/C++开发|Linux篇】https://www.bilibili.com/video/BV1fy4y1b7TC?p=17&vd_sourc......
  • Linux语法注意区分千万别记混!!!注意!!!
    Docker相关语法删除容器:dockerrm-f  容器名或容器ID删除镜像:dockerrmi-f  镜像名或镜像id导入镜像文件到本地dockerload-i  镜像压缩包文件名清理已关闭容器: docker  container prune查看已关闭容器:docker  ps  -a  查看数据卷: docker  volum......
  • 深入理解linux系统目录
    / 根目录。 包含了几乎所的文件目录。相当于中央系统。进入的最简单方法是:cd/。/boot 引导程序,内核等存放的目录。 这个目录,包括了在引导过程中所必需的文件,引导程序的相关文件(例如grub,lilo以及相应的配置文件以及Linux操作系统内核相关文件(例如vmlinuz等一般都存放在这里。在......
  • 基础linux命令
    前言:由于在实际开发过程中服务器大多部署在linux系统下,所以特此来学习linux的基本操作1.1pwdpwd命令的目的是打印当前目录,告诉你目前在哪里比如我在kali终端中输入pwd,实际返回为/home/kali1.2lsls可以列出当前目录下有什么文件当然也可以查看不同目录的内容,比如ls文件地......
  • 虚拟机VMware与乌班图的安装 -- 正点原子嵌入式Linux学习
    一、准备工作1、虚拟机VMware的下载官网下载地址:DownloadVMwareWorkstationPro2、linux乌班图的下载官网下载地址:下载Ubuntu桌面系统|Ubuntu二、虚拟机VMware的安装过程1、点击第一步下载好的虚拟机安装文件,选择自定义,后点击下一步2、点击稍后安装3、选择Linux......
  • linux自带i2c工具使用
    I2C总线被全球超过50个公司的1000+个ICs所使用,已然是一个世界标准.另外,I2C总线与多种不同的控制总线是兼容的,比如SMBus(系统管理总线),PMBus(电源管理总线),IPMI(智能平台管理总线),DDC(显示数据通道)以及ATCA(高级电信架构).如果没记错的话,linux中的I2C框架是完全支持SMBu......
  • 如何扩容Linux文件系统?看这里↓↓↓
    一、在虚拟机中添加一块新磁盘注意:如果是未关机的状态下,添加完新的虚拟磁盘需要重启才能生效查看当前系统内的磁盘数量,确认我们新添加的磁盘能正常显示了fdisk-l二、为新添加的磁盘创建分区fdisk/dev/sdb命令(输入m获取帮助):n #输入n创建分区分区类型p主分区(0......
  • Linux中进程相关的API
    在Linux中,进程控制相关的API非常多。以下是一些常用的进程控制相关的系统调用(syscalls)和库函数:创建和终止进程:fork():创建一个新进程,这是创建新进程的最常用方法。vfork():类似于fork(),但有一些差异,主要用于exec调用之前。exec():系列函数(如execl(),execp(),execle()......