2 Star 6 Fork 1

FreeAC/FreeAC

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
udphelp.c 6.45 KB
一键复制 编辑 原始数据 按行查看 历史
FreeAC 提交于 2015-12-28 00:58 . start
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* 版权所有 2014-2015 成都星锐蓝海网络科技有限公司
* 商业许可请联系 +86-18682011860 QQ:66442834
*
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h> // for getaddrinfo
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/select.h>
#include "xyz_log.h"
#include "udphelp.h"
static int udpSetNonblock(int fd)
{
int flags = 0;
if (fd < 0) {
xyz_log_error("argument is error");
return -1;
}
if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
xyz_log_error("fcntl : %s", strerror(errno));
return -1;
} else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK | O_ASYNC) != 0) {
xyz_log_error("fcntl : %s", strerror(errno));
return -1;
}
return 0;
}
int udpNewConnect(int nonblock, long msto)
{
int fd = -1;
struct sockaddr_in sin;
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
xyz_log_error("socket : %s", strerror(errno));
return -1;
}
if (1 == nonblock) {
if (udpSetNonblock(fd) < 0) {
close(fd);
return -1;
}
} else {
if (msto < 1) {
xyz_log_error("timeout value error");
close(fd);
return -1;
}
struct timeval tv;
tv.tv_sec = msto / 1000;
tv.tv_usec = (msto % 1000) * 1000;
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
xyz_log_error("setsockopt : %s", strerror(errno));
close(fd);
return -1;
}
}
memset(&sin, 0, sizeof sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(0);
if (bind(fd, (const struct sockaddr *)&(sin), sizeof(sin)) == -1) {
xyz_log_error("bind : %s", strerror(errno));
close(fd);
return -1;
}
return fd;
}
int udpNewLongConnect(const char *sip,
const char *sport,
const char *dip,
const char *dport,
int nonblock,
unsigned long msto)
{
int fd = -1;
int yes = 1;
struct sockaddr_in src;
struct sockaddr_in dst;
struct addrinfo hints;
struct addrinfo *res = NULL;
char myport[8] = { 0 };
if (!dip || !dport) {
xyz_log_error("arguments is error");
return -1;
}
memset(&dst, 0, sizeof(dst));
dst.sin_family = AF_INET;
dst.sin_addr.s_addr = inet_addr(dip);
dst.sin_port = htons(atol(dport));
if (dst.sin_port > 0xffff) {
xyz_log_error("port \"%s\" is invalid", dport);
return -1;
}
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
xyz_log_error("socket : %s", strerror(errno));
return -1;
}
if (1 == nonblock) {
if (udpSetNonblock(fd) < 0) {
close(fd);
return -1;
}
} else {
if (msto < 1) {
xyz_log_error("timeout value error");
close(fd);
return -1;
}
struct timeval tv;
tv.tv_sec = msto / 1000;
tv.tv_usec = (msto % 1000) * 1000;
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
xyz_log_error("setsockopt : %s", strerror(errno));
close(fd);
return -1;
}
}
if (!sip && !sport) {
memset(&hints, 0, sizeof (struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, myport, &hints, &res);
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) {
xyz_log_error("setsockopt : %s", strerror(errno));
close(fd);
return -1;
}
if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) {
xyz_log_error("bind : %s", strerror(errno));
close(fd);
return -1;
}
} else {
memset(&src, 0, sizeof(src));
src.sin_family = AF_INET;
if (!sip) {
src.sin_addr.s_addr = INADDR_ANY;
} else {
src.sin_addr.s_addr = inet_addr(sip);
}
src.sin_port = htons(atol(sport));
if (src.sin_port > 0xffff) {
xyz_log_error("remote port \"%s\" is invalid", sport);
close(fd);
return -1;
}
if (bind(fd, (struct sockaddr *)&src, sizeof(src)) < 0) {
xyz_log_error("bind : %s", strerror(errno));
close(fd);
return -1;
}
}
#if 0
if (connect(fd, (struct sockaddr *)&dst, sizeof(dst))) {
xyz_log_error("connect : %s", strerror(errno));
close(fd);
return -1;
}
#endif
return fd;
}
int udpNewServer(const char *ip,
uint16_t port,
int nonblock,
long msto)
{
int fd = -1;
struct sockaddr_in addr;
if(port < 1){
xyz_log_error("Args error");
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if (ip) {
addr.sin_addr.s_addr = inet_addr(ip);
} else {
addr.sin_addr.s_addr = htonl(INADDR_ANY);
}
addr.sin_port = htons(port);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0){
xyz_log_error("socket : %s", strerror(errno));
return (-1);
}
if (1 == nonblock) {
if (udpSetNonblock(fd) < 0) {
xyz_log_error("Set socket no block error");
close(fd);
return -1;
}
} else {
if (msto < 1) {
xyz_log_error("timeout value error");
close(fd);
return -1;
}
struct timeval tv;
tv.tv_sec = msto / 1000;
tv.tv_usec = (msto % 1000) * 1000;
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
xyz_log_error("setsockopt : %s", strerror(errno));
close(fd);
return -1;
}
}
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0){
xyz_log_error("bind : %s", strerror(errno));
close(fd);
return (-1);
}
return fd;
}
int udpTimeRecv(int fd, void *buff, int size, struct sockaddr_in *from, int msec)
{
int rc = 0;
struct timeval tv;
fd_set fset;
int addrlen = sizeof(struct sockaddr_in);
if (fd < 1 || !buff || !from) {
xyz_log_error("Arguments is error");
return -1;
}
tv.tv_sec = msec / 1000;
tv.tv_usec = ((msec % 1000) * 1000);
FD_ZERO(&fset);
FD_SET(fd, &fset);
rc = select(fd + 1, &fset, NULL, NULL, &tv);
if (rc > 0) {
if (FD_ISSET(fd, &fset)) {
rc = recvfrom(fd, buff, size, 0, (struct sockaddr *)from, &addrlen);
if (rc > 0) {
return rc;
} else {
xyz_log_error("recvfrom : %s", strerror(errno));
return -1;
}
} else {
xyz_log_error("select return not is FD %d", fd);
return -1;
}
} else if (0 == rc) {
xyz_log_debug("Select Time Expired");
return 0;
} else {
if (errno == EINTR) {
xyz_log_error("Select Interrupted by signal");
return -1;
}
}
return -1;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/freeac/FreeAC.git
git@gitee.com:freeac/FreeAC.git
freeac
FreeAC
FreeAC
master

搜索帮助