您的位置:首页 > 编程语言 > C语言/C++

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  udp C-C++