【ARM&Linux】UDP网络编程模型

2019-07-13 01:52发布

class="markdown_views prism-atelier-sulphurpool-light">

《UDP网络编程模型示例》



1、模型函数化

  • 【服务器】:
    1. 创建socket
    2. 绑定地址
    3. 收发数据
    4. 结束连接
  • 【客户端】:
    1. 创建socket
    2. 收发数据
    3. 结束连接

2、示例代码

/**************************************************************************************** * 文件名: service.c * 创建者: * 时 间: * 联 系: * 简 介: UDP程序设计模型,函数API参考文档《Unix环境高级编程》 *****************************************************************************************/ /*********************************************************** 函数学习及流程: 1、创建socket: 2、绑定地址: 3、接收数据:ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len); 参数一:指明哪个socket 参数二:用于存放收到的数据 参数三:接收多少字节 参数四:标志,一般为0 参数五:接收数据的目标地址 参数六:接收数据的目标地址的长度 返回值:成功返回接收到的字节书,失败-1 4、发送数据:ssize_t sendto(int socket, const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len); 参数一:指明是哪个socket 参数二:要发送的数据 参数三:要发送的数据长度 参数四:标志,一般为0 参数五:目标地址 参数六:目标地址长度 返回值:成功返回发送成功的字节数,失败-1 5、关闭套接字 本例程只详细介绍了发送和接收函数,其他函数详细信息见另一篇tcp编程的博客:http://blog.csdn.net/qq153471503/article/details/79329089 【综合实例】: 服务器一直接收数据并打印,直到收到end结束接收,然后发送向客户端发送通知数据。 客户端一直获取键盘输入并发送数据,并显示发送结果,键入end结束发送,并接收服务器的通知数据并打印。 ************************************************************/ #include "mytype.h" int main() { int fd; char buf[64]; socklen_t addr_length = sizeof(struct sockaddr_in); struct sockaddr_in server_addr; struct sockaddr_in client_addr; // 1、创建socket fd = socket(AF_INET, SOCK_DGRAM, 0); if(fd == -1) { DEBUG_ERROR("service creat socket failed. "); exit(EXIT_FAILURE); } // 2、绑定地址 bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(8080); server_addr.sin_family = AF_INET; bind(fd, &server_addr, sizeof(server_addr)); // 3、接收数据 bzero(&client_addr, sizeof(client_addr)); client_addr.sin_addr.s_addr = inet_addr("192.168.0.252"); client_addr.sin_port = htons(8080); client_addr.sin_family = AF_INET; while(1) { if( recvfrom(fd, buf, sizeof(buf), 0, &client_addr, &addr_length) > 0) { if(strncmp(buf, "end", 3) == 0) { break; } DEBUG_INFO("receive data from [%s] : %s ", inet_ntoa(client_addr.sin_addr), buf); } } bzero(buf, sizeof(buf)); strcpy(buf, "server stop. "); if( sendto(fd, buf, strlen(buf), 0, &client_addr, sizeof(client_addr)) <= 0 ) { DEBUG_WARNING("server send to client failed. "); }else{ DEBUG_INFO("server send result successful. "); } // 5、关闭 close(fd); return 0; } #include "mytype.h" /*********************************************************** 函数学习及流程: 1、创建 2、发送 3、接收 4、结束连接 ************************************************************/ int main() { int fd; char buf[64]; socklen_t addr_length = sizeof(struct sockaddr_in); struct sockaddr_in server_addr; struct sockaddr_in client_addr; // 1、创建socket fd = socket(AF_INET, SOCK_DGRAM, 0); if(fd == -1) { DEBUG_ERROR("service creat socket failed. "); exit(EXIT_FAILURE); } // 2、循环发送数据 bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_addr.s_addr = inet_addr("192.168.0.252"); server_addr.sin_port = htons(8080); server_addr.sin_family = AF_INET; while(1) { DEBUG_PRINTF("Please input : "); fgets(buf, sizeof(buf), stdin); if( sendto(fd, buf, strlen(buf), 0, &server_addr, sizeof(server_addr)) > 0 ) { DEBUG_INFO("client send successful. "); } if(strncmp(buf, "end", 3) == 0 ) { break; } } // 3、接收通知数据 bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(8080); server_addr.sin_family = AF_INET; // memset(buf, 0, sizeof(buf)); if(recvfrom(fd, buf, sizeof(buf), 0, &server_addr, &addr_length) > 0) { DEBUG_INFO("receive server data is : %s ", buf); } // 4、结束连接 close(fd); return 0; }

3、运行结果

  • 【Makefile】
    这里写图片描述
     
  • 【运行结果】
    这里写图片描述

4、mytype.h

/**************************************************************************************** * 文件名: mytype.h * 创建者: Kun * 联 系: 153471503@qq.com * 简 介: linux常用类型定义 * 最后修改时间: 2018/2/15 17:57 *****************************************************************************************/ #ifndef _MYTYPE_H_ #define _MYTYPE_H_ //--------------------------< 预添加头文件包含 >----------------------// #define USE_TIME 0 #define USE_SIGNAL 0 #define USE_SHARE_MEMORY 0 #define USE_SEMAPHORE_NAME 0 #define USE_SEMAPHORE_UNNAMED 0 #define USE_MSG_QUEUE 0 #define USE_FILE_CTL 0 #define USE_THREAD 0 #define USE_SOCKET 1 //-------------------------------< end ----------------------------// //---------------------------< includes >---------------------------// // c标准库头文件 #include #include #include #include #include // 信号使用相关头文件 #if USE_SIGNAL #include #endif // USE_SIGNAL // 有名信号量操作相关头文件 #if USE_SEMAPHORE #include #include #endif // USE_SEMAPHORE // 无名信号量操作相关头文件 #if USE_SEMAPHORE_UNNAMED #include #endif // USE_SEMAPHORE_UNNAMED // 共享内存操作相关头文件 #if USE_SHARE_MEMORY #include #endif // USE_SHARE_MEMORY // 消息队列相关头文件 #if USE_MSG_QUEUE #if !USE_SEMAPHORE #include #endif #include #endif // USE_MSG_QUEUE // 系统调用式文件编程头文件 #include // 该文件所定义的接口通常都是大量针对系统调用的封装, // 如 fork、pipe 以及各种 I/O 原语(read、write、close 等等)。 #include // linux系统中类型定义相关头文件 #include // 文件状态,是unix/linux系统定义文件状态所在的伪标准头文件。 #if USE_FILE_CTL #include #endif // USE_FILE_CTL // 时间编程相关头文件 #if USE_TIME #include #endif // USE_TIME // 线程相关头文件 #if USE_THREAD #include #endif // USE_THREAD // 网络编程相关头文件 #if USE_SOCKET #include #include #include #endif // USE_SEMAPHORE_NAME //-------------------------< includes end >-------------------------// // bool类型定义 #ifndef bool typedef unsigned int bool; #endif enum { true = 1, false = !true }; // 常用无符号数据类型定义 typedef unsigned int uint; typedef unsigned char uchar; typedef unsigned short ushort; //----------------------< 调试信息输入相关宏定义 >----------------------// #define DEBUG_INFO(...) printf("Info: "); printf(__VA_ARGS__) #define DEBUG_ERROR(...) printf("Error: "); printf(__VA_ARGS__) #define DEBUG_WARNING(...) printf("Warning: "); printf(__VA_ARGS__) #define DEBUG_PRINTF(...) printf(__VA_ARGS__) //------------------------------------------------------------------// // 有名信号量使用封装结构 #if USE_SEMAPHORE typedef struct sem_use SEM_USE; struct sem_use { int semid; key_t key; struct sembuf sops; }; #endif // USE_SEMAPHORE // 共享内存使用封装结构 #if USE_SHARE_MEMORY typedef struct shmem_use SHMEM_USE; struct shmem_use { int shmid; key_t key; }; #define BUF_SIZE 1024*1 //共享内存大小 typedef struct shmem_area SHMEM_AREA; struct shmem_area { bool isnull; char data[BUF_SIZE]; }; #endif // USE_SHARE_MEMORY // 消息队列使用封装结构 #if USE_MSG_QUEUE typedef struct msg_queue_use MSG_QUEUE_USE; struct msg_queue_use{ key_t key; int msgid; }; #endif // USE_MSG_QUEUE #if USE_SOCKET //tcp客户端使用封装结构 typedef struct use_tcp_client{ int fd; struct sockaddr_in server_addr; socklen_t addr_length; }USE_TCP_CLIENT; //tcp服务端使用结构封装 typedef struct use_tcp_service{ int fd; int newfd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; socklen_t addr_length; }USE_TCP_SERVICE; #endif // USE_SOCKET #endif // _TYPE_H_
ends