00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdnet.h"
00027
00028 #include "nel/net/tcp_sock.h"
00029
00030 #ifdef NL_OS_WINDOWS
00031 #include <winsock2.h>
00032 #define socklen_t int
00033 #define ERROR_NUM WSAGetLastError()
00034
00035 #elif defined NL_OS_UNIX
00036 #include <unistd.h>
00037 #include <sys/types.h>
00038 #include <sys/time.h>
00039 #include <sys/socket.h>
00040 #include <netinet/in.h>
00041 #include <netinet/tcp.h>
00042 #include <arpa/inet.h>
00043 #include <netdb.h>
00044 #include <errno.h>
00045 #define SOCKET_ERROR -1
00046 #define INVALID_SOCKET -1
00047 #define ERROR_NUM errno
00048 #define ERROR_MSG strerror(errno)
00049 typedef int SOCKET;
00050
00051 #endif
00052
00053 using namespace NLMISC;
00054
00055 namespace NLNET {
00056
00057
00058
00059
00060
00061 CTcpSock::CTcpSock( bool logging ) :
00062 CSock( logging )
00063 {}
00064
00065
00066
00067
00068
00069 CTcpSock::CTcpSock( SOCKET sock, const CInetAddress& remoteaddr ) :
00070 CSock( sock, remoteaddr )
00071 {}
00072
00073
00074
00075
00076
00077
00078
00079
00080 void CTcpSock::connect( const CInetAddress& addr )
00081 {
00082
00083 if ( _Sock != INVALID_SOCKET )
00084 {
00085 if ( _Logging )
00086 {
00087
00088 }
00089 close();
00090 }
00091 createSocket( SOCK_STREAM, IPPROTO_TCP );
00092
00093
00094 CSock::connect( addr );
00095 }
00096
00097
00098
00099
00100
00101 void CTcpSock::disconnect()
00102 {
00103 nldebug( "LNETL0: Socket %d disconnecting from %s...", _Sock, _RemoteAddr.asString().c_str() );
00104
00105
00106 #ifdef NL_OS_WINDOWS
00107 ::shutdown( _Sock, SD_BOTH );
00108 #elif defined NL_OS_UNIX
00109 ::shutdown( _Sock, SHUT_RDWR );
00110 #endif
00111
00112
00113 _Connected = false;
00114 }
00115
00116
00117
00118
00119
00120 void CTcpSock::shutdownReceiving()
00121 {
00122 #ifdef NL_OS_WINDOWS
00123 ::shutdown( _Sock, SD_RECEIVE );
00124 #elif defined NL_OS_UNIX
00125 ::shutdown( _Sock, SHUT_RD );
00126 #endif
00127 }
00128
00129
00130
00131
00132
00133 void CTcpSock::shutdownSending()
00134 {
00135 #ifdef NL_OS_WINDOWS
00136 ::shutdown( _Sock, SD_SEND );
00137 #elif defined NL_OS_UNIX
00138 ::shutdown( _Sock, SHUT_WR );
00139 #endif
00140 }
00141
00142
00143
00144
00145
00146 void CTcpSock::setNoDelay( bool value )
00147 {
00148 int b = value?1:0;
00149 if ( setsockopt( _Sock, IPPROTO_TCP, TCP_NODELAY, (char*)&b, sizeof(b) ) != 0 )
00150 {
00151 throw ESocket( "setNoDelay failed" );
00152 }
00153 }
00154
00155
00156
00157
00158
00159
00160
00161 void CTcpSock::connectWithCustomWindowSize( const CInetAddress& addr, int windowsize )
00162 {
00163
00164 if ( _Sock != INVALID_SOCKET )
00165 {
00166 nlerror( "Cannot connect with custom window size when already connected" );
00167 }
00168 createSocket( SOCK_STREAM, IPPROTO_TCP );
00169
00170
00171 if ( setsockopt( _Sock, SOL_SOCKET, SO_SNDBUF, (char*)&windowsize, sizeof(windowsize) ) != 0
00172 || setsockopt( _Sock, SOL_SOCKET, SO_RCVBUF, (char*)&windowsize, sizeof(windowsize) ) != 0 )
00173 {
00174 throw ESocket( "setWindowSize failed" );
00175 }
00176
00177
00178 CSock::connect( addr );
00179 }
00180
00181
00182
00183
00184
00185 uint32 CTcpSock::getWindowSize()
00186 {
00187 int windowsize = 0;
00188 socklen_t len = sizeof( windowsize );
00189
00190
00191 if ( getsockopt( _Sock, SOL_SOCKET, SO_SNDBUF, (char*) &windowsize, &len ) == 0 )
00192 {
00193 return windowsize;
00194 }
00195 else
00196 {
00197 return 0;
00198 }
00199 }
00200
00201
00202 }