网络编程值UDP

1. 知识点

1.1 TCP和UDP优缺点

1.2 UDP通信流程

1.2.1 服务端

1. 创建udp套接字

2. 初始化服务端网络地址结构  

3. 绑定服务端网络地址

4.创建结构体用来存储客户端网络地址结构

5. 接收客户数据

1.2.2 客户端

1. 创建udp套接字

2. 初始化服务器网络地址结构

3. 客户端先发送数据

2. 函数接口参考course-1

3. udp通信的接收和发送

udp_server.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

//udp通信
//服务端 和客户端 接收发送信息

int main(int argc,char** argv)
{
    //1. 创建udp套接字
    int socket_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2. 初始化服务端网络地址结构  //4.创建结构体cliaddr用来存储客户端网络地址结构
    struct sockaddr_in cliaddr,seraddr;//cliaddr客户  seraddr服务
    //初始化服务端地址
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(atoi(argv[2]));//设置端口 //主机字节序的短整型数据
    seraddr.sin_addr.s_addr = inet_addr(argv[1]);//将将点分十进制转转为无符号的32位网络地址

    socklen_t seraddr_len = sizeof(seraddr);
	socklen_t cliaddr_len = sizeof(cliaddr);

    //3. 绑定服务端网络地址
    int bind_ok = bind(socket_fd,(struct sockaddr*)&seraddr,seraddr_len);
    if(bind_ok==-1){
        perror("bind failed");
    }

    //监听,可有可无
    listen(socket_fd,4);

    char sbuf[128];//发送
    char rbuf[128];//接收

    while(1){

        memset(sbuf,0,sizeof(sbuf));
        memset(rbuf,0,sizeof(rbuf));

        //5. 接收客户数据,这里先接收客户发送的消息,第五个参数可以得到客户的地址
        recvfrom(socket_fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&cliaddr,&cliaddr_len);
        printf("server接收数据:%s\n",rbuf);

        //发送,发送个客户,因为我们recvfrom函数接收已经得到了客户地址了
        fgets(sbuf,sizeof(sbuf),stdin);
        sendto(socket_fd,sbuf,sizeof(sbuf),0,(struct sockaddr *)&cliaddr,cliaddr_len);
        printf("server发送数据:%s\n",sbuf);

        
        //退出
        if(strcmp("bye\n",sbuf)==0){
            break;
        }

        //退出
        if(strcmp("bye\n",rbuf)==0){
            break;
        }
    }   

    close(socket_fd);
    
    return 0;
}

udp_client.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

//udp通信
//客户端 和 服务端 发送接收信息

int main(int argc,char** argv)
{
    //1. 创建udp套接字
    int socket_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2. 初始化服务器网络地址结构
    struct sockaddr_in seraddr;//cliaddr客户  seraddr服务

    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(atoi(argv[2]));//设置端口 //主机字节序的短整型数据
    seraddr.sin_addr.s_addr = inet_addr(argv[1]);//将将点分十进制转转为无符号的32位网络地址
    socklen_t seraddr_len = sizeof(seraddr);


    //这个绑定可有可无
    // struct sockaddr_in cliaddr;
	// socklen_t cliaddr_len = sizeof(cliaddr);
    // int bind_ok = bind(socket_fd,(struct sockaddr*)&cliaddr,cliaddr_len);
    // if(bind_ok==-1){
    //     perror("bind failed");
    // }

    //监听,可有可无
    listen(socket_fd,4);

    char sbuf[128];//发送
    char rbuf[128];//接收

    while(1){

        memset(sbuf,0,sizeof(sbuf));
        memset(rbuf,0,sizeof(rbuf));

        //3. 客户端先发送数据,发给服务端,因为上面我们初始化了服务器地址结构
        fgets(sbuf,sizeof(sbuf),stdin);
        sendto(socket_fd,sbuf,sizeof(sbuf),0,(struct sockaddr *)&seraddr,seraddr_len);
        printf("client发送数据:%s\n",sbuf);

        //接收服务端数据
        recvfrom(socket_fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&seraddr,&seraddr_len);
        printf("client接收数据:%s\n",rbuf);
        
        //退出
        if(strcmp("bye\n",sbuf)==0){
            break;
        }
        
        //退出
        if(strcmp("bye\n",rbuf)==0){
            break;
        }
    }   

    close(socket_fd);
    
    return 0;
}

4. 可以将 通信的双发 接收和发送 写在一起

whole_udp.c

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

int sock_fd = -1;

void *recv_addr2(void *arg)
{
	struct sockaddr outside_addr = *(struct sockaddr *)arg;
	
	socklen_t addr2_len = sizeof(outside_addr);
	char sbuf[128];
	while(1)
	{
		memset(sbuf,0,sizeof(sbuf));

		fgets(sbuf,sizeof(sbuf),stdin);
		sendto(sock_fd,sbuf,sizeof(sbuf),0,(struct sockaddr *)&outside_addr,addr2_len);
	}
}

int main(int argc, char **argv)
{
	//创建udp套接字
	sock_fd = socket(AF_INET,SOCK_DGRAM,0);
	
	//定义结构体
	struct sockaddr_in local_addr, outside_addr;
	
	//自己本地的地址信息
	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(atoi(argv[2]));
	local_addr.sin_addr.s_addr = inet_addr(argv[1]);
	//计算本地大小
	socklen_t local_addr_len = sizeof(local_addr);
	//绑定本地
	bind(sock_fd,(struct sockaddr *)&local_addr,local_addr_len);
	
	//外地地址信息
	outside_addr.sin_family = AF_INET;
	outside_addr.sin_port = htons(atoi(argv[4]));
	outside_addr.sin_addr.s_addr = inet_addr(argv[3]);
	//计算外地大小
	socklen_t outside_addr_len = sizeof(outside_addr);

	//监听 ,可有可无
	listen(sock_fd,4);
	
	//创建线程
	pthread_t tid;
	//传参把外地地址信息传到线程函数中
	pthread_create(&tid,NULL,recv_addr2,(void *)&outside_addr);
	
	char rbuf[128];//接收
	
	while(1)
	{

		memset(rbuf,0,sizeof(rbuf));

		//接收,接收外地信息
		recvfrom(sock_fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&outside_addr,&outside_addr_len);

		//将是一个用于将 IPv4 地址从二进制形式转换为点分十进制字符串形式的C库函数。
		char *ip = inet_ntoa(outside_addr.sin_addr);//ip
		unsigned short port = ntohs(outside_addr.sin_port);//端口号
		
		printf("[来自%s  %u outside_addr]:%s\n",ip,port,rbuf);
	}

	
}

相关推荐

  1. 网络编程】-- 04 UDP

    2023-12-11 15:56:03       58 阅读
  2. linux网络----UDP编程

    2023-12-11 15:56:03       59 阅读
  3. 网络UDP编程

    2023-12-11 15:56:03       40 阅读
  4. 网络UDP编程

    2023-12-11 15:56:03       40 阅读
  5. UDP网络编程

    2023-12-11 15:56:03       39 阅读
  6. Linux——网络编程——UDP

    2023-12-11 15:56:03       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-11 15:56:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-11 15:56:03       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-11 15:56:03       82 阅读
  4. Python语言-面向对象

    2023-12-11 15:56:03       91 阅读

热门阅读

  1. 了解linux计划任务

    2023-12-11 15:56:03       58 阅读
  2. c++基础 循环遍历 新手学习

    2023-12-11 15:56:03       54 阅读
  3. 一篇文章读懂Jenkins的发展历程

    2023-12-11 15:56:03       62 阅读
  4. 使用Boost.Outcome模块进行容器相关的测试程序编程

    2023-12-11 15:56:03       47 阅读
  5. React基础知识入门

    2023-12-11 15:56:03       66 阅读
  6. PTA:哈夫曼编码

    2023-12-11 15:56:03       65 阅读
  7. mysql8.x创建insert/update/delete触发器

    2023-12-11 15:56:03       59 阅读
  8. 算法通关村第十七关 | 黄金挑战 | 跳跃游戏

    2023-12-11 15:56:03       68 阅读
  9. execution unit的概念与实现----AGU

    2023-12-11 15:56:03       54 阅读
  10. C++- 格式化输出

    2023-12-11 15:56:03       64 阅读