udp组播试验-C语言
2015-12-16 20:34
435 查看
example.c
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <bits/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <string.h> #include <unistd.h> #include <error.h> #include <errno.h> #include <time.h> #include <pthread.h> #define UDP_SERVER_BUF_LEN 1024 #define BROADCAST_PORT 10010 struct udpServerAttr_t { int sockfd; struct sockaddr_in serverAddr; //server address struct sockaddr_in clientAddr; //server address struct sockaddr_in broadcastAddr; char request[UDP_SERVER_BUF_LEN]; //request buffer }; int udpServer_init(struct udpServerAttr_t *self); int udpServer_exit(struct udpServerAttr_t *self); void *udpServer_threadRun(void *arg); int udpServer_sndMsg(int sockfd, struct sockaddr_in *clientAddr, char *data, int len); int udpServer_recvMsg(int sockfd, struct sockaddr_in *clientAddr, char *data, int len); int udpServer_clientSockInit(int *sockfd); int udpServer_serverSockInit(int *sockfd, struct sockaddr_in *serverAddr); int udpServer_clientAddrInit(struct sockaddr_in *clientAddr, const char *addr, int port); int udpServer_serverAddrInit(struct sockaddr_in *serverAddr, int port); int udpServer_sockAddrInit(struct sockaddr_in *clientAddr, const char *addr, int port); void udpServer_udpHandler(struct udpServerAttr_t *self); /** @brief 开启线程 @author - @param[in] run 线程入口 @param[in] arg 线程参数 @return 0 @note */ int threadStart(void *(*run)(void *), void *arg) { pthread_t threadId; pthread_attr_t threadAttr; memset(&threadAttr,0,sizeof(pthread_attr_t)); pthread_attr_init(&threadAttr); pthread_attr_setdetachstate(&threadAttr,PTHREAD_CREATE_DETACHED); int result = pthread_create(&threadId, &threadAttr, run, arg); pthread_attr_destroy(&threadAttr); printf("threadStart: threadId %ld\n", threadId); if(result != 0) { perror("threadStart: pthread_create"); return -1; } return threadId; } /** * @brief udp初始化函数 * @author - * @param[in]<self><适配器运行环境> * @return <-1: 失败, 0: 成功> */ int udpServer_init(struct udpServerAttr_t *self) { udpServer_sockAddrInit(&self->broadcastAddr, "255.255.255.255", 10001); udpServer_sockAddrInit(&self->serverAddr, "0.0.0.0", BROADCAST_PORT); if(udpServer_serverSockInit(&self->sockfd, &self->serverAddr) == -1) { perror("udpServer_init: udpServer_serverSockInit"); return -1; } return 0; } /** * @brief udp退出函数 * @author - * @param[in]<self><适配器运行环境> * @return <-1: 失败, 0: 成功> */ int udpServer_exit(struct udpServerAttr_t *self) { free(self); return 0; } /** * @brief udp主函数,处理udp网络消息和于子进程的消息 * @author - * @param[in]<arg><未用> */ void *udpServer_threadRun(void *arg) { struct udpServerAttr_t *udpServerAttr = (struct udpServerAttr_t *)malloc(sizeof(struct udpServerAttr_t)); if(NULL == udpServerAttr) { perror("udpServer_threadRun: malloc"); return NULL; } if(-1 == udpServer_init(udpServerAttr)) { udpServer_exit(udpServerAttr); return NULL; } while(1) { udpServer_udpHandler(udpServerAttr); usleep(100000); } udpServer_exit(udpServerAttr); return NULL; } /** * @brief udp服务器变量初始化函数 * @author - * @param[in|out]<serverAddr><服务属性> * @param[in]<port><绑定的端口> * @return <0: 成功> */ int udpServer_serverAddrInit(struct sockaddr_in *serverAddr, int port) { bzero(serverAddr,sizeof(struct sockaddr_in)); serverAddr->sin_family = AF_INET; serverAddr->sin_addr.s_addr = htonl(INADDR_ANY); serverAddr->sin_port = htons(port); return 0; } /** * @brief udp服务器变量初始化函数 * @author - * @param[in|out]<clientAddr><服务属性> * @param[in|out]<addr><客户端地址> * @param[in]<port><发送的端口> * @return <0: 成功> */ int udpServer_clientAddrInit(struct sockaddr_in *clientAddr, const char *addr, int port) { bzero(clientAddr,sizeof(struct sockaddr_in)); clientAddr->sin_family = AF_INET; clientAddr->sin_addr.s_addr = inet_addr(addr); clientAddr->sin_port = htons(port); return 0; } /** * @brief udp服务器变量初始化函数 * @author - * @param[in|out]<clientAddr><服务属性> * @param[in|out]<addr><客户端地址> * @param[in]<port><发送的端口> * @return <0: 成功> */ int udpServer_sockAddrInit(struct sockaddr_in *clientAddr, const char *addr, int port) { bzero(clientAddr,sizeof(struct sockaddr_in)); clientAddr->sin_family = AF_INET; clientAddr->sin_addr.s_addr = inet_addr(addr); clientAddr->sin_port = htons(port); return 0; } void udpServer_udpHandler(struct udpServerAttr_t *self) { int ret = udpServer_recvMsg(self->sockfd, &self->clientAddr, self->request, UDP_SERVER_BUF_LEN); if(0 == ret) { printf("udpServer_udpHandler %s\n", self->request); udpServer_sndMsg(self->sockfd, &self->clientAddr, self->request, 100); } } /** * @brief udp客户端初始化函数 * @author - * @param[in]<sockfd><描述符> * @return <-1: 失败, 0: 成功> */ int udpServer_clientSockInit(int *sockfd) { *sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(*sockfd == -1) { return -1; } int sockOpt = 1; /*turn on*/ if(setsockopt(*sockfd, SOL_SOCKET, SO_BROADCAST, &sockOpt, sizeof(int)) != 0) { return -1; } sockOpt = 1; if(setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &sockOpt, sizeof(int)) != 0) { return -1; } return 0; } /** * @brief udp服务器初始化函数 * @author - * @param[in|out]<sockfd><描述符> * @param[in|out]<serverAddr><服务属性> * @return <-1: 失败, 0: 成功> */ int udpServer_serverSockInit(int *sockfd, struct sockaddr_in *serverAddr) { *sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(*sockfd == -1) { perror("udpServer_serverSockInit: socket"); return -1; } int sockOpt = 1; /*turn on*/ // if(setsockopt(*sockfd, SOL_SOCKET, SO_BROADCAST, &sockOpt, sizeof(int)) != 0) { // perror("udpServer_serverSockInit: setsockopt"); // return -1; // } struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr("224.0.1.255"); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if(setsockopt(*sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq)) != 0) { perror("udpServer_serverSockInit: setsockopt IPPROTO_IP"); return -1; } sockOpt = 1; if(setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &sockOpt, sizeof(int)) != 0) { perror("udpServer_serverSockInit: setsockopt SO_REUSEADDR"); return -1; } if(bind(*sockfd ,(struct sockaddr *)serverAddr, sizeof(struct sockaddr)) == -1) { perror("udpServer_serverSockInit: bind"); return -1; } return 0; } /** * @brief udp发送函数 * @author - * @param[in]<sockfd><描述符> * @param[in]<clientAddr><服务属性> * @param[in]<data><发送的数据> * @param[in]<len><发送的数据的长度> * @return <-1: 失败, 0: 成功> */ int udpServer_sndMsg(int sockfd, struct sockaddr_in *clientAddr, char *data, int len) { if(sendto(sockfd, data, len, 0, (struct sockaddr *)clientAddr, sizeof(struct sockaddr)) == -1) { return -1; } return 0; } /** * @brief 接收udp数据函数 * @author - * @param[in]<sockfd><描述符> * @param[in]<clientAddr><服务属性> * @param[in]<data><接收数据的缓冲区> * @param[in]<len><接收数据缓冲区的长度> * @return <-1: 失败, 0: 成功> */ int udpServer_recvMsg(int sockfd, struct sockaddr_in *clientAddr, char *data, int len) { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(sockfd, &fds); timeout.tv_sec = 1; timeout.tv_usec = 0; socklen_t ipLen = sizeof(struct sockaddr); switch(select(sockfd+1,&fds,NULL,NULL,&timeout)) { case -1:return -1; case 0:return -1; default: if(FD_ISSET(sockfd, &fds)) { if(recvfrom(sockfd, data, len, 0, (struct sockaddr *)clientAddr, &ipLen) == -1) { return -1; } else { } } break; } return 0; } int main(int argc, char *argv[]) { threadStart(udpServer_threadRun, NULL); while(1) { sleep(100); } return 0; }
相关文章推荐
- C#基于UDP实现的P2P语音聊天工具
- C#基于UDP进行异步通信的方法
- 距离详解Linux下的UDP方式通讯
- C#中使用UDP通信实例
- Linux网络编程之UDP Socket程序示例
- 服务器 UDP端口占用几千个的解决办法
- Android网络编程之UDP通信模型实例
- udp socket客户端和udp服务端程序示例分享
- PHP的Socket通信之UDP通信实例
- Android编程实现基于局域网udp广播自动建立socket连接的方法
- Android中实现TCP和UDP传输实例
- android开发socket编程之udp发送实例分析
- Linux网络编程之基于UDP实现可靠的文件传输示例
- java编程实现基于UDP协议传输数据的方法
- python检测远程udp端口是否打开的方法
- python网络编程之数据传输UDP实例分析
- python基础教程之udp端口扫描
- python实现udp数据报传输的方法
- Python里disconnect UDP套接字的方法
- Java基于socket服务实现UDP协议的方法