1 // ------------------------------------------------
6 // Windows version of ClientSocket. Handles the nitty gritty of actually
7 // reading and writing TCP
9 // (c) 2002 peercast.org
10 // ------------------------------------------------
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 // ------------------------------------------------
22 // TODO: fix socket closing
26 //#include "winsock2.h"
32 #include "chkMemoryLeak.h"
33 #define DEBUG_NEW new(__FILE__, __LINE__)
38 // --------------------------------------------------
39 void WSAClientSocket::init()
41 WORD wVersionRequested;
45 wVersionRequested = MAKEWORD( 2, 0 );
46 err = WSAStartup( wVersionRequested, &wsaData );
48 throw SockException("Unable to init sockets");
50 //LOG4("WSAStartup: OK");
53 // --------------------------------------------------
54 bool ClientSocket::getHostname(char *str,unsigned int ip)
60 he = gethostbyaddr((char *)&ip,sizeof(ip),AF_INET);
64 strcpy(str,he->h_name);
70 unsigned int cache_ip = 0;
71 unsigned int cache_time = 0;
73 // --------------------------------------------------
74 unsigned int ClientSocket::getIP(char *name)
76 unsigned int ctime = sys->getTime();
77 bool null_flg = (name == NULL);
80 if ((cache_time != 0) && (cache_time + 60 > ctime)){
92 if (gethostname(szHostName, sizeof(szHostName))==0)
98 HOSTENT *he = WSAClientSocket::resolveHost(name);
104 LPSTR lpAddr = he->h_addr_list[0];
108 struct in_addr inAddr;
109 memmove (&inAddr, lpAddr, 4);
111 ret = inAddr.S_un.S_un_b.s_b1<<24 |
112 inAddr.S_un.S_un_b.s_b2<<16 |
113 inAddr.S_un.S_un_b.s_b3<<8 |
114 inAddr.S_un.S_un_b.s_b4;
124 // --------------------------------------------------
125 void WSAClientSocket::setLinger(int sec)
128 linger.l_onoff = (sec>0)?1:0;
129 linger.l_linger = sec;
131 if (setsockopt(sockNum, SOL_SOCKET, SO_LINGER, (const char *)&linger, sizeof (linger)) == -1)
132 throw SockException("Unable to set LINGER");
135 // --------------------------------------------------
136 void WSAClientSocket::setBlocking(bool yes)
138 unsigned long op = yes ? 0 : 1;
139 if (ioctlsocket(sockNum, FIONBIO, &op) == SOCKET_ERROR)
140 throw SockException("Can`t set blocking");
142 // --------------------------------------------------
143 void WSAClientSocket::setNagle(bool on)
145 int nodelay = (on==false);
146 if (setsockopt(sockNum, SOL_SOCKET, TCP_NODELAY, (char *)&nodelay, sizeof nodelay) == -1)
147 throw SockException("Unable to set NODELAY");
151 // --------------------------------------------------
152 void WSAClientSocket::setReuse(bool yes)
154 unsigned long op = yes ? 1 : 0;
155 if (setsockopt(sockNum,SOL_SOCKET,SO_REUSEADDR,(char *)&op,sizeof(unsigned long)) == -1)
156 throw SockException("Unable to set REUSE");
159 // --------------------------------------------------
160 void WSAClientSocket::setBufSize(int size)
164 int len = sizeof(op);
165 if (getsockopt(sockNum,SOL_SOCKET,SO_RCVBUF,(char *)&oldop,&len) == -1) {
166 LOG_DEBUG("Unable to get RCVBUF");
167 } else if (oldop < size) {
168 if (setsockopt(sockNum,SOL_SOCKET,SO_RCVBUF,(char *)&op,len) == -1)
169 LOG_DEBUG("Unable to set RCVBUF");
171 // LOG_DEBUG("*** recvbufsize:%d -> %d", oldop, op);
174 if (getsockopt(sockNum,SOL_SOCKET,SO_SNDBUF,(char *)&oldop,&len) == -1) {
175 LOG_DEBUG("Unable to get SNDBUF");
176 } else if (oldop < size) {
177 if (setsockopt(sockNum,SOL_SOCKET,SO_SNDBUF,(char *)&op,len) == -1)
178 LOG_DEBUG("Unable to set SNDBUF");
180 // LOG_DEBUG("*** sendbufsize: %d -> %d", oldop, op);
184 // --------------------------------------------------
185 HOSTENT *WSAClientSocket::resolveHost(const char *hostName)
189 if ((he = gethostbyname(hostName)) == NULL)
191 // if failed, try using gethostbyaddr instead
193 unsigned long ip = inet_addr(hostName);
195 if (ip == INADDR_NONE)
198 if ((he = gethostbyaddr((char *)&ip,sizeof(ip),AF_INET)) == NULL)
204 // --------------------------------------------------
205 void WSAClientSocket::open(Host &rh)
207 sockNum = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
209 if (sockNum == INVALID_SOCKET)
210 throw SockException("Can`t open socket");
220 memset(&remoteAddr,0,sizeof(remoteAddr));
222 remoteAddr.sin_family = AF_INET;
223 remoteAddr.sin_port = htons(host.port);
224 remoteAddr.sin_addr.S_un.S_addr = htonl(host.ip);
227 // --------------------------------------------------
228 void WSAClientSocket::checkTimeout(bool r, bool w)
230 int err = WSAGetLastError();
231 if (err == WSAEWOULDBLOCK)
241 FD_ZERO (&write_fds);
244 timeout.tv_sec = (int)this->writeTimeout/1000;
245 FD_SET (sockNum, &write_fds);
251 timeout.tv_sec = (int)this->readTimeout/1000;
252 FD_SET (sockNum, &read_fds);
262 int r=select (NULL, &read_fds, &write_fds, NULL, tp);
265 throw TimeoutException();
266 else if (r == SOCKET_ERROR)
267 throw SockException("select failed.");
271 sprintf(str,"%d",err);
272 throw SockException(str);
276 // --------------------------------------------------
277 void WSAClientSocket::checkTimeout2(bool r, bool w)
288 FD_ZERO (&write_fds);
291 timeout.tv_sec = (int)this->writeTimeout/1000;
292 FD_SET (sockNum, &write_fds);
298 timeout.tv_sec = (int)this->readTimeout/1000;
299 FD_SET (sockNum, &read_fds);
309 int r=select (NULL, &read_fds, &write_fds, NULL, tp);
312 throw TimeoutException();
313 else if (r == SOCKET_ERROR)
314 throw SockException("select failed.");
318 // --------------------------------------------------
319 Host WSAClientSocket::getLocalHost()
321 struct sockaddr_in localAddr;
323 int len = sizeof(localAddr);
324 if (getsockname(sockNum, (sockaddr *)&localAddr, &len) == 0)
325 return Host(SWAP4(localAddr.sin_addr.s_addr),0);
330 // --------------------------------------------------
331 void WSAClientSocket::connect()
333 if (::connect(sockNum,(struct sockaddr *)&remoteAddr,sizeof(remoteAddr)) == SOCKET_ERROR)
334 checkTimeout(false,true);
337 // --------------------------------------------------
338 int WSAClientSocket::read(void *p, int l)
344 if (rbDataSize >= l) {
345 memcpy(p, &apReadBuf[rbPos], l);
349 } else if (rbDataSize > 0) {
350 memcpy(p, &apReadBuf[rbPos], rbDataSize);
351 p = (char *) p + rbDataSize;
353 bytesRead += rbDataSize;
358 //int r = recv(sockNum, (char *)p, l, 0);
359 int r = recv(sockNum, apReadBuf, RBSIZE, 0);
360 if (r == SOCKET_ERROR)
362 // non-blocking sockets always fall through to here
363 checkTimeout(true,false);
367 throw EOFException("Closed on read");
371 stats.add(Stats::BYTESIN,r);
373 stats.add(Stats::LOCALBYTESIN,r);
384 // --------------------------------------------------
385 int WSAClientSocket::readUpto(void *p, int l)
390 int r = recv(sockNum, (char *)p, l, 0);
391 if (r == SOCKET_ERROR)
393 // non-blocking sockets always fall through to here
394 //checkTimeout(true,false);
402 stats.add(Stats::BYTESIN,r);
404 stats.add(Stats::LOCALBYTESIN,r);
410 if (bytesRead) break;
416 // --------------------------------------------------
417 void WSAClientSocket::write(const void *p, int l)
421 int r = send(sockNum, (char *)p, l, 0);
422 if (r == SOCKET_ERROR)
424 checkTimeout(false,true);
428 throw SockException("Closed on write");
433 stats.add(Stats::BYTESOUT,r);
435 stats.add(Stats::LOCALBYTESOUT,r);
444 // --------------------------------------------------
445 void WSAClientSocket::bufferingWrite(const void *p, int l)
447 if (bufList.isNull() && p != NULL){
449 int r = send(sockNum, (char *)p, l, 0);
450 if (r == SOCKET_ERROR){
451 int err = WSAGetLastError();
452 if (err == WSAEWOULDBLOCK){
454 // LOG_DEBUG("normal add");
458 sprintf(str,"%d",err);
459 throw SockException(str);
462 throw SockException("Closed on write");
464 stats.add(Stats::BYTESOUT,r);
466 stats.add(Stats::LOCALBYTESOUT,r);
474 // LOG_DEBUG("***************BufferingWrite");
482 tmp = bufList.getTop();
485 // LOG_DEBUG("tmp->pos = %d, tmp->len = %d, %d", tmp->pos, tmp->len, tmp);
486 while(tmp->pos < tmp->len){
487 int r = send(sockNum, (char*)(tmp->buf + tmp->pos), tmp->len - tmp->pos, 0);
488 // LOG_DEBUG("send = %d", r);
489 if (r == SOCKET_ERROR){
490 int err = WSAGetLastError();
491 if (err == WSAEWOULDBLOCK){
497 sprintf(str,"%d",err);
498 throw SockException(str);
502 throw SockException("Closed on write");
504 stats.add(Stats::BYTESOUT,r);
506 stats.add(Stats::LOCALBYTESOUT,r);
511 if (tmp->pos >= tmp->len){
512 // LOG_DEBUG("deleteTop");
522 // LOG_DEBUG("bufferingWrite end");
526 // --------------------------------------------------
527 void WSAClientSocket::checkBuffering(bool r, bool w)
529 int err = WSAGetLastError();
530 if (err == WSAEWOULDBLOCK)
540 FD_ZERO (&write_fds);
543 timeout.tv_sec = (int)this->writeTimeout/1000;
544 FD_SET (sockNum, &write_fds);
550 timeout.tv_sec = (int)this->readTimeout/1000;
551 FD_SET (sockNum, &read_fds);
561 int r=select (NULL, &read_fds, &write_fds, NULL, tp);
564 throw TimeoutException();
565 else if (r == SOCKET_ERROR)
566 throw SockException("select failed.");
570 sprintf(str,"%d",err);
571 throw SockException(str);
575 // --------------------------------------------------
576 void WSAClientSocket::bind(Host &h)
578 struct sockaddr_in localAddr;
580 if ((sockNum = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
581 throw SockException("Can`t open socket");
586 memset(&localAddr,0,sizeof(localAddr));
587 localAddr.sin_family = AF_INET;
588 localAddr.sin_port = htons(h.port);
589 localAddr.sin_addr.s_addr = INADDR_ANY;
591 if( ::bind (sockNum, (sockaddr *)&localAddr, sizeof(localAddr)) == -1)
592 throw SockException("Can`t bind socket");
594 if (::listen(sockNum,SOMAXCONN))
595 throw SockException("Can`t listen",WSAGetLastError());
599 // --------------------------------------------------
600 ClientSocket *WSAClientSocket::accept()
603 int fromSize = sizeof(sockaddr_in);
606 int conSock = ::accept(sockNum,(sockaddr *)&from,&fromSize);
609 if (conSock == INVALID_SOCKET)
613 WSAClientSocket *cs = new WSAClientSocket();
614 cs->sockNum = conSock;
616 cs->host.port = (from.sin_port & 0xff) << 8 | ((from.sin_port >> 8) & 0xff);
617 cs->host.ip = from.sin_addr.S_un.S_un_b.s_b1<<24 |
618 from.sin_addr.S_un.S_un_b.s_b2<<16 |
619 from.sin_addr.S_un.S_un_b.s_b3<<8 |
620 from.sin_addr.S_un.S_un_b.s_b4;
623 cs->setBlocking(false);
627 cs->setBufSize(65535);
632 // --------------------------------------------------
633 void WSAClientSocket::close()
638 // shutdown(sockNum,SD_SEND);
640 setReadTimeout(2000);
641 unsigned int stime = sys->getTime();
645 while (read(&c, sizeof(c)) > 0)
646 if (sys->getTime() - stime > 5)
648 }catch(StreamException &) {}
650 if (closesocket (sockNum))
651 LOG_ERROR("closesocket() error");
659 // --------------------------------------------------
660 bool WSAClientSocket::readReady()
662 if (rbDataSize) return true;
671 FD_SET (sockNum, &read_fds);
673 return select (sockNum+1, &read_fds, NULL, NULL, &timeout) == 1;