📄 sockctl.c
字号:
{ C_error_set_errno(C_EINVAL); return(FALSE); } if(s->sfp) { fclose(s->sfp); s->sfp = NULL; } return(TRUE); }/* */static c_bool_t __C_socket_reopen(c_socket_t *s, int sd) { int flags, i, type, sz; if(sd < 0) { C_error_set_errno(C_EINVAL); return(FALSE); } if((flags = fcntl(sd, F_GETFL, 0)) == -1) { C_error_set_errno(C_EFCNTL); return(FALSE); } /* get socket type */ sz = (int)sizeof(int); if(getsockopt(sd, SOL_SOCKET, SO_TYPE, (char *)&type, &sz)) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } for(i = 0; i < C_NET_MAXTYPE; i++) if(type == __C_net_socktypes[i]) break; if(i == C_NET_MAXTYPE) { C_error_set_errno(C_EBADTYPE); return(FALSE); } s->sd = sd; s->type = i; s->state = C_NET_CONNECTED; /* get socket's local address */ i = sizeof(struct sockaddr_in); if(getsockname(s->sd, (struct sockaddr *)&(s->laddr), &i) < 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } /* get socket's remote address */ i = sizeof(struct sockaddr_in); if(getpeername(sd, (struct sockaddr *)&(s->raddr), &i) < 0) { switch(errno) { case ENOTCONN: s->state = C_NET_CREATED; break; default: C_error_set_errno(C_ESOCKINFO); return(FALSE); } } /* get flags */ if(flags & O_NONBLOCK) s->flags |= C_NET_MUNBLOCK; return(TRUE); }/* */c_socket_t *C_socket_reopen(int sd) { c_socket_t *s = C_new(c_socket_t); if(!__C_socket_reopen(s, sd)) return(C_free(s)); return(s); }/* */c_bool_t C_socket_reopen_s(c_socket_t *s, int sd) { if(!s) { C_error_set_errno(C_EINVAL); return(FALSE); } C_zero(s, c_socket_t); return(__C_socket_reopen(s, sd)); }/* */c_bool_t C_socket_set_option(c_socket_t *s, uint_t option, c_bool_t flag, uint_t value) { if(! s) { C_error_set_errno(C_EINVAL); return(FALSE); } switch(option) { // block case C_NET_OPT_BLOCK: { int flags; if(s->state == C_NET_SHUTDOWN) { C_error_set_errno(C_EBADSTATE); return(FALSE); } if((flags = fcntl(s->sd, F_GETFL, 0)) == -1) { C_error_set_errno(C_EFCNTL); return(FALSE); } flag ? (flags &= ~O_NONBLOCK) : (flags |= O_NONBLOCK); flag ? (s->flags &= ~C_NET_MUNBLOCK) : (s->flags |= C_NET_MUNBLOCK); if(fcntl(s->sd, F_SETFL, flags) == -1) { C_error_set_errno(C_EFCNTL); return(FALSE); } return(TRUE); } // linger case C_NET_OPT_LINGER: { struct linger l; l.l_onoff = (flag ? 1 : 0); l.l_linger = value; if(setsockopt(s->sd, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(struct linger)) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); } // reuse address case C_NET_OPT_REUSEADDR: { int v = flag; if(setsockopt(s->sd, SOL_SOCKET, SO_REUSEADDR, (char *)&v, sizeof(int)) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); } // oob data inline case C_NET_OPT_OOBINLINE: { int v = flag; if(setsockopt(s->sd, SOL_SOCKET, SO_OOBINLINE, (char *)&v, sizeof(int)) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); } // keepalive case C_NET_OPT_KEEPALIVE: { int v = flag; if(setsockopt(s->sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, sizeof(int)) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); } // recv buffer case C_NET_OPT_RECVBUF: { int v = (int)value; if(setsockopt(s->sd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(int)) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); } // send buffer case C_NET_OPT_SENDBUF: { int v = (int)value; if(setsockopt(s->sd, SOL_SOCKET, SO_SNDBUF, (char *)&v, sizeof(int)) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); } // unknown default: C_error_set_errno(C_EINVAL); return(FALSE); } }/* */c_bool_t C_socket_get_option(c_socket_t *s, uint_t option, c_bool_t *flag, uint_t *value) { if(!s || !flag || !value) { C_error_set_errno(C_EINVAL); return(FALSE); } switch(option) { // block case C_NET_OPT_BLOCK: { return(!(s->flags & C_NET_MUNBLOCK)); } // linger case C_NET_OPT_LINGER: { int sz = sizeof(struct linger); struct linger l; if(getsockopt(s->sd, SOL_SOCKET, SO_LINGER, (char *)&l, &sz) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } *flag = l.l_onoff ? TRUE : FALSE; *value = (uint_t)l.l_linger; return(TRUE); } // reuse address case C_NET_OPT_REUSEADDR: { int sz = sizeof(int); int v; if(getsockopt(s->sd, SOL_SOCKET, SO_REUSEADDR, (char *)&v, &sz) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } *flag = v ? TRUE : FALSE; return(TRUE); } // oob data inline case C_NET_OPT_OOBINLINE: { int sz = sizeof(int); int v; if(getsockopt(s->sd, SOL_SOCKET, SO_OOBINLINE, (char *)&v, &sz) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } *flag = v ? TRUE : FALSE; return(TRUE); } // keepalive case C_NET_OPT_KEEPALIVE: { int sz = sizeof(int); int v; if(getsockopt(s->sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, &sz) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } *flag = v ? TRUE : FALSE; return(TRUE); } // recv buffer case C_NET_OPT_RECVBUF: { int sz = sizeof(int); int v; if(getsockopt(s->sd, SOL_SOCKET, SO_RCVBUF, (char *)&v, &sz) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } *value = (uint_t)v; return(TRUE); } // send buffer case C_NET_OPT_SENDBUF: { int sz = sizeof(int); int v; if(getsockopt(s->sd, SOL_SOCKET, SO_SNDBUF, (char *)&v, &sz) != 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } *value = (uint_t)v; return(TRUE); } // unknown default: C_error_set_errno(C_EINVAL); return(FALSE); } }/* */c_bool_t C_socket_mcast_join(c_socket_t *s, const char *addr) { struct ip_mreq mreq; struct sockaddr_in saddr; if(! s || !addr) { C_error_set_errno(C_EINVAL); return(FALSE); } if(!*addr) { C_error_set_errno(C_EINVAL); return(FALSE); } if(s->type != C_NET_UDP) { C_error_set_errno(C_EBADTYPE); return(FALSE); } if(! __C_socket_addr2sock(&saddr, addr)) { C_error_set_errno(C_EADDRINFO); return(FALSE); } memcpy(&mreq.imr_multiaddr, &(saddr.sin_addr), sizeof(struct in_addr)); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if(setsockopt(s->sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); }/* */c_bool_t C_socket_mcast_leave(c_socket_t *s, const char *addr) { struct ip_mreq mreq; struct sockaddr_in saddr; if(! s || !addr) { C_error_set_errno(C_EINVAL); return(FALSE); } if(!*addr) { C_error_set_errno(C_EINVAL); return(FALSE); } if(s->type != C_NET_UDP) { C_error_set_errno(C_EBADTYPE); return(FALSE); } if(! __C_socket_addr2sock(&saddr, addr)) { C_error_set_errno(C_EADDRINFO); return(FALSE); } memcpy(&mreq.imr_multiaddr, &(saddr.sin_addr), sizeof(struct in_addr)); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if(setsockopt(s->sd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); }/* */c_bool_t C_socket_mcast_set_ttl(c_socket_t *s, c_byte_t ttl) { if(!s) { C_error_set_errno(C_EINVAL); return(FALSE); } if(s->type != C_NET_UDP) { C_error_set_errno(C_EBADTYPE); return(FALSE); } if(setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); }/* */c_bool_t C_socket_mcast_set_loop(c_socket_t *s, c_bool_t loop) { u_char flag = (u_char)loop; if(!s) { C_error_set_errno(C_EINVAL); return(FALSE); } if(s->type != C_NET_UDP) { C_error_set_errno(C_EBADTYPE); return(FALSE); } if(setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_LOOP, &flag, sizeof(flag)) < 0) { C_error_set_errno(C_ESOCKINFO); return(FALSE); } return(TRUE); }/* end of source file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -