📄 socket.cpp
字号:
*port = 0; memset((void*) &peer.ipv6, 0, sizeof(peer.ipv6)); }#else if(rtn < 1) { if(port) *port = 0; memset((void*) &peer.ipv6, 0, sizeof(peer.ipv6)); }#endif else { if(port) *port = ntohs(peer.ipv6.sin6_port); } return IPV6Host(peer.ipv6.sin6_addr);}#endifUDPBroadcast::UDPBroadcast(const IPV4Address &ia, tpport_t port) :UDPSocket(ia, port){ if(so != INVALID_SOCKET) setBroadcast(true);}void UDPBroadcast::setPeer(const IPV4Broadcast &ia, tpport_t port){ memset(&peer.ipv4, 0, sizeof(peer.ipv4)); peer.ipv4.sin_family = AF_INET; peer.ipv4.sin_addr = getaddress(ia); peer.ipv4.sin_port = htons(port);}void TCPSocket::setSegmentSize(unsigned mss){#ifdef TCP_MAXSEG if(mss > 1) setsockopt(so, IPPROTO_TCP, TCP_MAXSEG, (char *)&mss, sizeof(mss));#endif segsize = mss;}#ifdef HAVE_GETADDRINFOTCPSocket::TCPSocket(const char *name, unsigned backlog, unsigned mss) :Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP){ char namebuf[128], *cp; struct addrinfo hint, *list = NULL, *first; snprintf(namebuf, sizeof(namebuf), "%s", name); cp = strrchr(namebuf, '/'); if(!cp) cp = strrchr(namebuf, ':'); if(!cp) { cp = namebuf; name = NULL; } else { name = namebuf; *(cp++) = 0; if(!strcmp(name, "*")) name = NULL; } memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_INET; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; hint.ai_flags = AI_PASSIVE; if(getaddrinfo(name, cp, &hint, &list) || !list) { endSocket(); error(errBindingFailed, "Could not find service", errno); return; }#if defined(SO_REUSEADDR) && !defined(WIN32) int opt = 1; setsockopt(so, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, (socklen_t)sizeof(opt));#endif first = list; while(list) { if(!bind(so, list->ai_addr, (socklen_t)list->ai_addrlen)) { state = BOUND; break; } list = list->ai_next; } freeaddrinfo(first); if(state != BOUND) { endSocket(); error(errBindingFailed,"Could not bind socket",socket_errno); return; } setSegmentSize(mss); if(listen(so, backlog)) { endSocket(); error(errBindingFailed,"Could not listen on socket",socket_errno); return; }}#elseTCPSocket::TCPSocket(const char *name, unsigned backlog, unsigned mss) :Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP){ char namebuf[128], *cp; struct sockaddr_in addr; struct servent *svc; memset(&addr, 0, sizeof(addr)); snprintf(namebuf, sizeof(namebuf), "%s", name); cp = strrchr(namebuf, '/'); if(!cp) cp = strrchr(namebuf, ':'); if(!cp) { cp = namebuf; name = "*"; } else { name = namebuf; *(cp++) = 0; } addr.sin_family = AF_INET; if(isdigit(*cp)) addr.sin_port = htons(atoi(cp)); else { mutex.enter(); svc = getservbyname(cp, "tcp"); if(svc) addr.sin_port = svc->s_port; mutex.leave(); if(!svc) { endSocket(); error(errBindingFailed, "Could not find service", errno); return; } } IPV4Address ia(name); addr.sin_addr = getaddress(ia);#if defined(SO_REUSEADDR) && !defined(WIN32) int opt = 1; setsockopt(so, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, (socklen_t)sizeof(opt));#endif if(bind(so, (struct sockaddr *)&addr, sizeof(addr))) { endSocket(); error(errBindingFailed,"Could not bind socket",socket_errno); return; } setSegmentSize(mss); if(listen(so, backlog)) { endSocket(); error(errBindingFailed,"Could not listen on socket", socket_errno); return; } state = BOUND;}#endif TCPSocket::TCPSocket(const IPV4Address &ia, tpport_t port, unsigned backlog, unsigned mss) :Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP){ struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = getaddress(ia); addr.sin_port = htons(port);#if defined(SO_REUSEADDR) && !defined(WIN32) int opt = 1; setsockopt(so, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, (socklen_t)sizeof(opt));#endif if(bind(so, (struct sockaddr *)&addr, sizeof(addr))) { endSocket(); error(errBindingFailed,"Could not bind socket",socket_errno); return; } setSegmentSize(mss); if(listen(so, backlog)) { endSocket(); error(errBindingFailed,"Could not listen on socket",socket_errno); return; } state = BOUND;}bool TCPSocket::onAccept(const IPV4Host &ia, tpport_t port){ return true;}TCPSocket::~TCPSocket(){ endSocket();}#ifdef CCXX_IPV6void TCPV6Socket::setSegmentSize(unsigned mss){#ifdef TCP_MAXSEG if(mss > 1) setsockopt(so, IPPROTO_TCP, TCP_MAXSEG, (char *)&mss, sizeof(mss));#endif segsize = mss;}#ifdef HAVE_GETADDRINFOTCPV6Socket::TCPV6Socket(const char *name, unsigned backlog, unsigned mss) :Socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP){ char namebuf[128], *cp; struct addrinfo hint, *list = NULL, *first; snprintf(namebuf, sizeof(namebuf), "%s", name); cp = strrchr(namebuf, '/'); if(!cp) { cp = namebuf; name = NULL; } else { name = namebuf; *(cp++) = 0; if(!strcmp(name, "*")) name = NULL; } memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_INET6; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; hint.ai_flags = AI_PASSIVE; if(getaddrinfo(name, cp, &hint, &list) || !list) { endSocket(); error(errBindingFailed, "Could not find service", errno); return; }#if defined(SO_REUSEADDR) && !defined(WIN32) int opt = 1; setsockopt(so, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, (socklen_t)sizeof(opt));#endif first = list; while(list) { if(!bind(so, list->ai_addr, (socklen_t)list->ai_addrlen)) { state = BOUND; break; } list = list->ai_next; } freeaddrinfo(first); if(state != BOUND) { endSocket(); error(errBindingFailed,"Could not bind socket",socket_errno); return; } setSegmentSize(mss); if(listen(so, backlog)) { endSocket(); error(errBindingFailed,"Could not listen on socket",socket_errno); return; }}#elseTCPV6Socket::TCPV6Socket(const char *name, unsigned backlog, unsigned mss) :Socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP){ char namebuf[128], *cp; struct sockaddr_in6 addr; struct servent *svc; memset(&addr, 0, sizeof(addr)); snprintf(namebuf, sizeof(namebuf), "%s", name); cp = strrchr(namebuf, '/'); if(!cp) { cp = namebuf; name = "*"; } else { name = namebuf; *(cp++) = 0; } addr.sin6_family = AF_INET6; if(isdigit(*cp)) addr.sin6_port = htons(atoi(cp)); else { mutex.enter(); svc = getservbyname(cp, "tcp"); if(svc) addr.sin6_port = svc->s_port; mutex.leave(); if(!svc) { endSocket(); error(errBindingFailed, "Could not find service", errno); return; } } IPV6Address ia(name); addr.sin6_addr = getaddress(ia);#if defined(SO_REUSEADDR) && !defined(WIN32) int opt = 1; setsockopt(so, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, (socklen_t)sizeof(opt));#endif if(bind(so, (struct sockaddr *)&addr, sizeof(addr))) { endSocket(); error(errBindingFailed,"Could not bind socket",socket_errno); return; } setSegmentSize(mss); if(listen(so, backlog)) { endSocket(); error(errBindingFailed,"Could not listen on socket", socket_errno); return; } state = BOUND;}#endif TCPV6Socket::TCPV6Socket(const IPV6Address &ia, tpport_t port, unsigned backlog, unsigned mss) :Socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP){ struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_addr = getaddress(ia); addr.sin6_port = htons(port);#if defined(SO_REUSEADDR) && !defined(WIN32) int opt = 1; setsockopt(so, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, (socklen_t)sizeof(opt));#endif if(bind(so, (struct sockaddr *)&addr, sizeof(addr))) { endSocket(); error(errBindingFailed,"Could not bind socket",socket_errno); return; } setSegmentSize(mss); if(listen(so, backlog)) { endSocket(); error(errBindingFailed,"Could not listen on socket",socket_errno); return; } state = BOUND;}bool TCPV6Socket::onAccept(const IPV6Host &ia, tpport_t port){ return true;}TCPV6Socket::~TCPV6Socket(){ endSocket();}#endifvoid TCPSocket::reject(void){ SOCKET rej = accept(so, NULL, NULL); shutdown(rej, 2);#ifdef WIN32 closesocket(rej);#else close(rej);#endif}#ifdef CCXX_IPV6void TCPV6Socket::reject(void){ SOCKET rej = accept(so, NULL, NULL); shutdown(rej, 2);#ifdef WIN32 closesocket(rej);#else close(rej);#endif}#endifTCPStream::TCPStream(TCPSocket &server, bool throwflag, timeout_t to) : streambuf(), Socket(accept(server.getSocket(), NULL, NULL)),#ifdef HAVE_OLD_IOSTREAM iostream()#else iostream((streambuf *)this)#endif ,bufsize(0) ,gbuf(NULL) ,pbuf(NULL){ tpport_t port; family = IPV4;#ifdef HAVE_OLD_IOSTREAM init((streambuf *)this);#endif timeout = to; setError(throwflag); IPV4Host host = getPeer(&port); if(!server.onAccept(host, port)) { endSocket(); error(errConnectRejected); clear(ios::failbit | rdstate()); return; } segmentBuffering(server.getSegmentSize()); Socket::state = CONNECTED;}#ifdef CCXX_IPV6TCPStream::TCPStream(TCPV6Socket &server, bool throwflag, timeout_t to) : streambuf(), Socket(accept(server.getSocket(), NULL, NULL)),#ifdef HAVE_OLD_IOSTREAM iostream()#else iostream((streambuf *)this)#endif ,bufsize(0) ,gbuf(NULL) ,pbuf(NULL){ tpport_t port; family = IPV6;#ifdef HAVE_OLD_IOSTREAM init((streambuf *)this);#endif timeout = to; setError(throwflag); IPV6Host host = getIPV6Peer(&port); if(!server.onAccept(host, port)) { endSocket(); error(errConnectRejected); clear(ios::failbit | rdstate()); return; } segmentBuffering(server.getSegmentSize()); Socket::state = CONNECTED;}#endifTCPStream::TCPStream(const IPV4Host &host, tpport_t port, unsigned size, bool throwflag, timeout_t to) : streambuf(), Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP),#ifdef HAVE_OLD_IOSTREAM iostream(),#else iostream((streambuf *)this),#endif bufsize(0),gbuf(NULL),pbuf(NULL){#ifdef HAVE_OLD_IOSTREAM init((streambuf *)this);#endif family = IPV4; timeout = to; setError(throwflag); connect(host, port, size);}#ifdef CCXX_IPV6TCPStream::TCPStream(const IPV6Host &host, tpport_t port, unsigned size, bool throwflag, timeout_t to) : streambuf(), Socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP),#ifdef HAVE_OLD_IOSTREAM iostream(),#else iostream((streambuf *)this),#endif bufsize(0),gbuf(NULL),pbuf(NULL){ family = IPV6;#ifdef HAVE_OLD_IOSTREAM init((streambuf *)this);#endif timeout = to; setError(throwflag); connect(host, port, size);}#endifTCPStream::~TCPStream(){#ifdef CCXX_EXCEPTIONS try { endStream(); } catch( ... ) { if ( ! std::uncaught_exception()) throw;}; #else endStream();#endif}#ifdef HAVE_GETADDRINFOvoid TCPStream::connect(const char *target, unsigned mss){ char namebuf[128]; char *cp; struct addrinfo hint, *list = NULL, *next, *first; bool connected = false; socklen_t alen = sizeof(mss); snprintf(namebuf, sizeof(namebuf), "%s", target); cp = strrchr(namebuf, '/'); if(!cp) cp = strrchr(namebuf, ':'); if(!cp) { endStream(); connectError(); return; } *(cp++) = 0; memset(&hint, 0, sizeof(hint)); hint.ai_family = family; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; if(getaddrinfo(namebuf, cp, &hint, &list) || !list) { endStream(); connectError(); return; } first = list;#ifdef TCP_MAXSEG if(mss) setsockopt(so, IPPROTO_TCP, TCP_MAXSEG, (char *)&mss, sizeof(mss));#endif while(list) { if(!::connect(so, list->ai_addr, (socklen_t)list->ai_addrlen)) { connected = true; break; } next = list->ai_next; list = next; } freeaddrinfo(first); if(!connected) { endStream(); connectError(); return; } segmentBuffering(mss); Socket::state = CONNECTED;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -