⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp.c

📁 linux下的飞鸽传书 日本人设计 使用非常方便
💻 C
字号:
#include "common.h"#include <stddef.h>#include <netdb.h>#include <pwd.h>#include <errno.h>#include <time.h>#include <unistd.h>#include <fcntl.h>#include <ctype.h>#include <sys/wait.h>#include <sys/mman.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/param.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <string.h>intinternal_realloc(void **ptr,size_t new_size,size_t old_size){  void *orig_ptr;  ssize_t clr_len;  if (!ptr)    return -1;  orig_ptr=*ptr;  *ptr=realloc(*ptr, new_size);    if (!(*ptr)) {    *ptr=orig_ptr;    return -2;  }  clr_len=new_size - old_size;  if (clr_len > 0)    memset( ((*ptr)+old_size),0,clr_len);  return 0;}const char *udp_get_peeraddr(const udp_con_t *con){  int rc;  struct addrinfo *info;  g_assert(con);  info=con->server_info;  g_assert(info);  rc=getnameinfo(info->ai_addr, info->ai_addrlen,		 (char *)con->peer, NI_MAXHOST,		NULL, 0, 		NI_NUMERICHOST);  g_assert (!rc);  dbg_out("get peer host:%s (family,type,proto)=(%d,%d,%d)\n",	  con->peer,	  info->ai_family,	  info->ai_socktype,	  info->ai_protocol);  return (const char *)con->peer;}int udp_setup_server(udp_con_t *con,int port,int family){  int rc;  int soc;  char reuse=1;  struct addrinfo *info;  if (!con)    return -EINVAL;  memset(con,0,sizeof(udp_con_t));  rc=setup_addr_info(&info, NULL,port,SOCK_DGRAM,family);  if (rc<0)    return rc;  rc=socket(info->ai_family,info->ai_socktype,info->ai_protocol);  if (rc<0)     goto err_out;  soc=rc;#ifdef IPV6_V6ONLY  if (info->ai_family == AF_INET6) {    int v6only=1;    rc=setsockopt(soc,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&v6only,sizeof(v6only));    if (rc) {      goto err_out;    }  }#endif /*  IPV6_V6ONLY  */  rc=bind(soc,info->ai_addr,info->ai_addrlen);  if (rc<0)    goto err_out;  con->client_info=info;  con->soc=soc;  con->family=family;  con->port=port;  /*   *allocate server side   */  rc=setup_addr_info(&info, NULL,port,SOCK_DGRAM,family);  if (rc<0)    goto free_client_out;  con->server_info=info;    return 0; free_client_out:  if (con->client_info)    freeaddrinfo(con->client_info);  con->client_info=NULL; err_out:  err_out("Error:%s (%d)\n",strerror(errno),errno);  if (info)    freeaddrinfo(info);  exit(rc);  return rc;}intudp_setup_client(udp_con_t *con,const char *hostname, int port,int family){  int soc;  int rc;  struct addrinfo *info=NULL;  if (!hostname)    return -EINVAL;  rc=setup_addr_info(&info, hostname,port,SOCK_DGRAM,family);  if (rc<0)    goto err_out;  rc=socket(info->ai_family,info->ai_socktype,info->ai_protocol);  if (rc<0)     goto free_out;    soc=rc;#ifdef IPV6_V6ONLY  if (info->ai_family == AF_INET6) {    int v6only=1;    rc=setsockopt(soc,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&v6only,sizeof(v6only));    if (rc) {      goto err_out;    }  }#endif /*  IPV6_V6ONLY  */  con->server_info=info;  con->soc=soc;  con->family=family;  con->port=port;  return 0; free_out:  if (info)    freeaddrinfo(info); err_out:  err_out("Error: %s (%d)\n",strerror(errno),errno);  return rc;}intudp_release_connection(udp_con_t *con) {  if (!con)    return -EINVAL;  dbg_out("Close udp sock:%d\n",con->soc);  if (con->client_info)    freeaddrinfo(con->client_info);  if (con->server_info)    freeaddrinfo(con->server_info);  con->client_info=NULL;  con->server_info=NULL;  close(con->soc);  return 0;}intudp_send_message(const udp_con_t *con,const char *ipaddr,int port, const char *msg,size_t len){  int rc;  struct addrinfo *info=NULL;  if ((!con) || (!ipaddr) || (!msg) )    return -EINVAL;  dbg_out("send [addr:%s port:%d]:\n %s\n",ipaddr,port,msg);  rc=setup_addr_info(&info,ipaddr,port,SOCK_DGRAM,con->family);  if (rc<0)    goto err_out;  rc=sendto(con->soc,msg,len,0,info->ai_addr,info->ai_addrlen); err_out:  if (info)    freeaddrinfo(info);  return rc;}intudp_send_peer(const udp_con_t *con,const char *msg,size_t len){  int rc;  struct addrinfo *info;  if ((!con) || (!msg) )    return -EINVAL;  dbg_out("send peer:%s\n",msg);  info=con->server_info;  g_assert(info);  rc=sendto(con->soc,msg,len,0,info->ai_addr,info->ai_addrlen);  return rc;}intudp_send_broadcast_with_addr(const udp_con_t *con,const char *bcast,const char *msg,size_t len){  int rc;  struct addrinfo *info=NULL;  if ((!con) || (!msg) )    return -EINVAL;  udp_enable_broadcast(con);  dbg_out("%s\n",msg);  if (!bcast) {    switch(con->family) {    case PF_INET6:      rc=setup_addr_info(&info,"ff02::1",con->port,SOCK_DGRAM,con->family);      break;    default:      rc=setup_addr_info(&info,"255.255.255.255",con->port,SOCK_DGRAM,con->family);      break;    }  } else {    rc=setup_addr_info(&info,bcast,con->port,SOCK_DGRAM,con->family);  }  if (rc<0)    goto err_out;  rc=sendto(con->soc,msg,len,0,info->ai_addr,info->ai_addrlen); err_out:  if (info)    freeaddrinfo(info);  return rc;}intudp_send_broadcast(const udp_con_t *con,const char *msg,size_t len){  return udp_send_broadcast_with_addr(con,NULL,msg,len);}static intudp_set_buffer(const udp_con_t *con){  int rc;  int size=0;  if (!con)    return -EINVAL;  return sock_set_buffer(con->soc);;}intudp_enable_broadcast(const udp_con_t *con){  int rc;  int flag;  int confirm,confirm_len;  if (!con)     return -EINVAL;  dbg_out("Here\n");  flag=1;  rc=setsockopt(con->soc, SOL_SOCKET, SO_BROADCAST, (void*)&flag, sizeof(int));  if (rc<0) {    err_out("Can not set broad cast:%s(%d)\n",strerror(errno),errno);    return -errno;  }  confirm=0;  confirm_len=sizeof(confirm);  rc=getsockopt(con->soc, SOL_SOCKET, SO_BROADCAST, (void*)&confirm, &confirm_len);  if (rc<0) {    err_out("Can not get broad cast:%s(%d)\n",strerror(errno),errno);    return -errno;  }  if (confirm)    dbg_out("Broadcat is set\n");  else    err_out("Can not set broad cast:%s(%d)\n",strerror(errno),errno);  return 0;}intudp_disable_broadcast(const udp_con_t *con){  int rc;  int flag;  if (!con)     return -EINVAL;  dbg_out("Here\n");  flag=0;  rc=setsockopt(con->soc, SOL_SOCKET, SO_BROADCAST, (void*)&flag, sizeof(int));  if (rc<0) {    err_out("Can not unset broad cast:%s(%d)\n",strerror(errno),errno);    return -errno;  }  return 0;}intudp_recv_message(const udp_con_t *con,char **msg,size_t *len){  ssize_t recv_len;  char *recv_buf=NULL;  int old_fd_flags;  int rc;  int ret_code=0;  struct addrinfo *info;  if ( (!con) || (!msg) || (!len) )    return -EINVAL;  g_assert(*msg==NULL);    recv_buf=malloc(_MSG_BUF_SIZE);  if (!recv_buf)    return -ENOMEM;  rc=udp_set_buffer(con);  if (rc<0)    goto err_out;  rc=udp_enable_broadcast(con);  if (rc<0)    goto err_out;  info=con->server_info;  /*   *  空読みする   */  recv_len=recvfrom(con->soc,recv_buf,_MSG_BUF_SIZE,(MSG_PEEK|MSG_DONTWAIT),info->ai_addr,&(info->ai_addrlen));  if (recv_len<=0) {    err_out("%s(errno:%d)\n",strerror(errno),errno);    ret_code=-errno;    goto err_out;  }  dbg_out("read:%d %s\n",recv_len,recv_buf);  /*   *  バッファに読み込む   */  recv_len=recvfrom(con->soc,recv_buf,recv_len,MSG_DONTWAIT,info->ai_addr,&(info->ai_addrlen));  if (recv_len<0) {    err_out("%s(errno:%d)\n",strerror(errno),errno);    ret_code=-errno;    goto err_out;  }  /*   * バッファ獲得   */    g_assert(*msg==NULL);  *msg=malloc(recv_len);  if (!(*msg))    goto err_out;  dbg_out("copy:%d %s\n",recv_len,recv_buf);  *len=recv_len;  memmove(*msg,recv_buf,recv_len);  /*  内容をコピー  */err_out:  if (recv_buf)    free(recv_buf);  return ret_code;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -