📄 socketft_8cpp-source.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"><title>Crypto++: socketft.cpp Source File</title><link href="doxygen.css" rel="stylesheet" type="text/css"></head><body><!-- Generated by Doxygen 1.3.2 --><div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Compound List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Compound Members</a> | <a class="qindex" href="globals.html">File Members</a></div><h1>socketft.cpp</h1><div class="fragment"><pre>00001 <span class="comment">// socketft.cpp - written and placed in the public domain by Wei Dai</span>00002 00003 <span class="preprocessor">#include "pch.h"</span>00004 <span class="preprocessor">#include "socketft.h"</span>00005 00006 <span class="preprocessor">#ifdef SOCKETS_AVAILABLE</span>00007 <span class="preprocessor"></span>00008 <span class="preprocessor">#include "wait.h"</span>00009 00010 <span class="preprocessor">#ifdef USE_BERKELEY_STYLE_SOCKETS</span>00011 <span class="preprocessor"></span><span class="preprocessor">#include <errno.h></span>00012 <span class="preprocessor">#include <netdb.h></span>00013 <span class="preprocessor">#include <unistd.h></span>00014 <span class="preprocessor">#include <arpa/inet.h></span>00015 <span class="preprocessor">#include <netinet/in.h></span>00016 <span class="preprocessor">#include <sys/ioctl.h></span>00017 <span class="preprocessor">#endif</span>00018 <span class="preprocessor"></span>00019 NAMESPACE_BEGIN(CryptoPP)00020 00021 #ifdef USE_WINDOWS_STYLE_SOCKETS00022 <span class="keyword">const</span> <span class="keywordtype">int</span> SOCKET_EINVAL = WSAEINVAL;00023 <span class="keyword">const</span> <span class="keywordtype">int</span> SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK;00024 <span class="keyword">typedef</span> <span class="keywordtype">int</span> socklen_t;00025 <span class="preprocessor">#else</span>00026 <span class="preprocessor"></span><span class="keyword">const</span> <span class="keywordtype">int</span> SOCKET_EINVAL = EINVAL;00027 <span class="keyword">const</span> <span class="keywordtype">int</span> SOCKET_EWOULDBLOCK = EWOULDBLOCK;00028 <span class="preprocessor">#endif</span>00029 <span class="preprocessor"></span>00030 Socket::Err::Err(socket_t s, <span class="keyword">const</span> std::string& operation, <span class="keywordtype">int</span> error)00031 : <a class="code" href="class_o_s___error.html">OS_Error</a>(IO_ERROR, "<a class="code" href="class_socket.html">Socket</a>: " + operation + " operation failed with error " + IntToString(error), operation, error)00032 , m_s(s)00033 {00034 }00035 00036 Socket::~Socket()00037 {00038 <span class="keywordflow">if</span> (m_own)00039 {00040 <span class="keywordflow">try</span>00041 {00042 CloseSocket();00043 }00044 <span class="keywordflow">catch</span> (...)00045 {00046 }00047 }00048 }00049 00050 <span class="keywordtype">void</span> Socket::AttachSocket(socket_t s, <span class="keywordtype">bool</span> own)00051 {00052 <span class="keywordflow">if</span> (m_own)00053 CloseSocket();00054 00055 m_s = s;00056 m_own = own;00057 SocketChanged();00058 }00059 00060 socket_t Socket::DetachSocket()00061 {00062 socket_t s = m_s;00063 m_s = INVALID_SOCKET;00064 SocketChanged();00065 <span class="keywordflow">return</span> s;00066 }00067 00068 <span class="keywordtype">void</span> Socket::Create(<span class="keywordtype">int</span> nType)00069 {00070 assert(m_s == INVALID_SOCKET);00071 m_s = socket(AF_INET, nType, 0);00072 CheckAndHandleError(<span class="stringliteral">"socket"</span>, m_s);00073 m_own = <span class="keyword">true</span>;00074 SocketChanged();00075 }00076 00077 <span class="keywordtype">void</span> Socket::CloseSocket()00078 {00079 <span class="keywordflow">if</span> (m_s != INVALID_SOCKET)00080 {00081 <span class="preprocessor">#ifdef USE_WINDOWS_STYLE_SOCKETS</span>00082 <span class="preprocessor"></span> CheckAndHandleError_int(<span class="stringliteral">"closesocket"</span>, closesocket(m_s));00083 <span class="preprocessor">#else</span>00084 <span class="preprocessor"></span> CheckAndHandleError_int(<span class="stringliteral">"close"</span>, close(m_s));00085 <span class="preprocessor">#endif</span>00086 <span class="preprocessor"></span> m_s = INVALID_SOCKET;00087 SocketChanged();00088 }00089 }00090 00091 <span class="keywordtype">void</span> Socket::Bind(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> port, <span class="keyword">const</span> <span class="keywordtype">char</span> *addr)00092 {00093 sockaddr_in sa;00094 memset(&sa, 0, <span class="keyword">sizeof</span>(sa));00095 sa.sin_family = AF_INET;00096 00097 <span class="keywordflow">if</span> (addr == NULL)00098 sa.sin_addr.s_addr = htonl(INADDR_ANY);00099 <span class="keywordflow">else</span>00100 {00101 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> result = inet_addr(addr);00102 <span class="keywordflow">if</span> (result == -1) <span class="comment">// Solaris doesn't have INADDR_NONE</span>00103 {00104 <a class="code" href="class_socket.html#_socket_sourcee4">SetLastError</a>(SOCKET_EINVAL);00105 CheckAndHandleError_int(<span class="stringliteral">"inet_addr"</span>, SOCKET_ERROR);00106 }00107 sa.sin_addr.s_addr = result;00108 }00109 00110 sa.sin_port = htons((u_short)port);00111 00112 Bind((sockaddr *)&sa, <span class="keyword">sizeof</span>(sa));00113 }00114 00115 <span class="keywordtype">void</span> Socket::Bind(<span class="keyword">const</span> sockaddr *psa, socklen_t saLen)00116 {00117 assert(m_s != INVALID_SOCKET);00118 <span class="comment">// cygwin workaround: needs const_cast</span>00119 CheckAndHandleError_int(<span class="stringliteral">"bind"</span>, bind(m_s, const_cast<sockaddr *>(psa), saLen));00120 }00121 00122 <span class="keywordtype">void</span> Socket::Listen(<span class="keywordtype">int</span> backlog)00123 {00124 assert(m_s != INVALID_SOCKET);00125 CheckAndHandleError_int(<span class="stringliteral">"listen"</span>, listen(m_s, backlog));00126 }00127 00128 <span class="keywordtype">bool</span> Socket::Connect(<span class="keyword">const</span> <span class="keywordtype">char</span> *addr, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> port)00129 {00130 assert(addr != NULL);00131 00132 sockaddr_in sa;00133 memset(&sa, 0, <span class="keyword">sizeof</span>(sa));00134 sa.sin_family = AF_INET;00135 sa.sin_addr.s_addr = inet_addr(addr);00136 00137 <span class="keywordflow">if</span> (sa.sin_addr.s_addr == -1) <span class="comment">// Solaris doesn't have INADDR_NONE</span>00138 {00139 hostent *lphost = gethostbyname(addr);00140 <span class="keywordflow">if</span> (lphost == NULL)00141 {00142 <a class="code" href="class_socket.html#_socket_sourcee4">SetLastError</a>(SOCKET_EINVAL);00143 CheckAndHandleError_int(<span class="stringliteral">"gethostbyname"</span>, SOCKET_ERROR);00144 }00145 00146 sa.sin_addr.s_addr = ((in_addr *)lphost->h_addr)->s_addr;00147 }00148 00149 sa.sin_port = htons((u_short)port);00150 00151 <span class="keywordflow">return</span> Connect((<span class="keyword">const</span> sockaddr *)&sa, <span class="keyword">sizeof</span>(sa));00152 }00153 00154 <span class="keywordtype">bool</span> Socket::Connect(<span class="keyword">const</span> sockaddr* psa, socklen_t saLen)00155 {00156 assert(m_s != INVALID_SOCKET);00157 <span class="keywordtype">int</span> result = connect(m_s, const_cast<sockaddr*>(psa), saLen);00158 <span class="keywordflow">if</span> (result == SOCKET_ERROR && <a class="code" href="class_socket.html#_socket_sourcee3">GetLastError</a>() == SOCKET_EWOULDBLOCK)00159 <span class="keywordflow">return</span> <span class="keyword">false</span>;00160 CheckAndHandleError_int(<span class="stringliteral">"connect"</span>, result);00161 <span class="keywordflow">return</span> <span class="keyword">true</span>;00162 }00163 00164 <span class="keywordtype">bool</span> Socket::Accept(<a class="code" href="class_socket.html">Socket</a>& target, sockaddr *psa, socklen_t *psaLen)00165 {00166 assert(m_s != INVALID_SOCKET);00167 socket_t s = accept(m_s, psa, psaLen);00168 <span class="keywordflow">if</span> (s == INVALID_SOCKET && <a class="code" href="class_socket.html#_socket_sourcee3">GetLastError</a>() == SOCKET_EWOULDBLOCK)00169 <span class="keywordflow">return</span> <span class="keyword">false</span>;00170 CheckAndHandleError_int(<span class="stringliteral">"accept"</span>, s);00171 target.<a class="code" href="class_socket.html#_socket_sourcea28">AttachSocket</a>(s, <span class="keyword">true</span>);00172 <span class="keywordflow">return</span> <span class="keyword">true</span>;00173 }00174 00175 <span class="keywordtype">void</span> Socket::GetSockName(sockaddr *psa, socklen_t *psaLen)00176 {00177 assert(m_s != INVALID_SOCKET);00178 CheckAndHandleError_int(<span class="stringliteral">"getsockname"</span>, getsockname(m_s, psa, psaLen));00179 }00180 00181 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Socket::Send(<span class="keyword">const</span> byte* buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bufLen, <span class="keywordtype">int</span> flags)00182 {00183 assert(m_s != INVALID_SOCKET);00184 <span class="keywordtype">int</span> result = send(m_s, (<span class="keyword">const</span> <span class="keywordtype">char</span> *)buf, bufLen, flags);00185 CheckAndHandleError_int(<span class="stringliteral">"send"</span>, result);00186 <span class="keywordflow">return</span> result;00187 }00188 00189 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Socket::Receive(byte* buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bufLen, <span class="keywordtype">int</span> flags)00190 {00191 assert(m_s != INVALID_SOCKET);00192 <span class="keywordtype">int</span> result = recv(m_s, (<span class="keywordtype">char</span> *)buf, bufLen, flags);00193 CheckAndHandleError_int(<span class="stringliteral">"recv"</span>, result);00194 <span class="keywordflow">return</span> result;00195 }00196 00197 <span class="keywordtype">void</span> Socket::ShutDown(<span class="keywordtype">int</span> how)00198 {00199 assert(m_s != INVALID_SOCKET);00200 <span class="keywordtype">int</span> result = shutdown(m_s, how);00201 CheckAndHandleError_int(<span class="stringliteral">"shutdown"</span>, result);00202 }00203 00204 <span class="keywordtype">void</span> Socket::IOCtl(<span class="keywordtype">long</span> cmd, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> *argp)00205 {00206 assert(m_s != INVALID_SOCKET);00207 <span class="preprocessor">#ifdef USE_WINDOWS_STYLE_SOCKETS</span>00208 <span class="preprocessor"></span> CheckAndHandleError_int(<span class="stringliteral">"ioctlsocket"</span>, ioctlsocket(m_s, cmd, argp));00209 <span class="preprocessor">#else</span>00210 <span class="preprocessor"></span> CheckAndHandleError_int(<span class="stringliteral">"ioctl"</span>, ioctl(m_s, cmd, argp));00211 <span class="preprocessor">#endif</span>00212 <span class="preprocessor"></span>}00213 00214 <span class="keywordtype">bool</span> Socket::SendReady(<span class="keyword">const</span> timeval *timeout)00215 {00216 fd_set fds;00217 FD_ZERO(&fds);00218 FD_SET(m_s, &fds);00219 <span class="keywordtype">int</span> ready;00220 <span class="keywordflow">if</span> (timeout == NULL)00221 ready = select(m_s+1, NULL, &fds, NULL, NULL);00222 <span class="keywordflow">else</span>00223 {00224 timeval timeoutCopy = *timeout; <span class="comment">// select() modified timeout on Linux</span>00225 ready = select(m_s+1, NULL, &fds, NULL, &timeoutCopy);00226 }00227 CheckAndHandleError_int(<span class="stringliteral">"select"</span>, ready);00228 <span class="keywordflow">return</span> ready > 0;00229 }00230 00231 <span class="keywordtype">bool</span> Socket::ReceiveReady(<span class="keyword">const</span> timeval *timeout)00232 {00233 fd_set fds;00234 FD_ZERO(&fds);00235 FD_SET(m_s, &fds);00236 <span class="keywordtype">int</span> ready;00237 <span class="keywordflow">if</span> (timeout == NULL)00238 ready = select(m_s+1, &fds, NULL, NULL, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -