00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 module mango.io.Socket;
00070
00071 private import mango.utils.Text;
00072
00073 private import mango.base.System;
00074
00075 private import mango.io.Resource,
00076 mango.io.Exception;
00077
00078 private import mango.io.model.IBuffer;
00079
00080
00081
00082
00083
00084
00085 version (linux)
00086 {
00087 version = BsdSockets;
00088 }
00089
00090 version (darwin)
00091 {
00092 version = BsdSockets;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 version (Win32)
00102 {
00103 typedef int socket_t = ~0;
00104 }
00105 else
00106 version (BsdSockets)
00107 {
00108 typedef int socket_t = -1;
00109 }
00110 else
00111 {
00112 static assert (0);
00113 }
00114
00115 private:
00116
00117 const socket_t INVALID_SOCKET = socket_t.init;
00118 const int SOCKET_ERROR = -1;
00119
00120
00121
00122
00123
00124
00125
00126
00127 static this()
00128 {
00129 version (Win32)
00130 {
00131 WSADATA wd;
00132 if (WSAStartup(0x0101, &wd))
00133 throw new SocketException("Unable to initialize socket library.");
00134 }
00135 }
00136
00137
00138 static ~this()
00139 {
00140 Socket.cancelAll (true);
00141 version (Win32)
00142 {
00143 WSACleanup();
00144 }
00145 }
00146
00147
00148
00149 private import std.stdint;
00150
00151
00152
00153
00154
00155
00156
00157 version(Win32)
00158 {
00159 import std.c.windows.windows;
00160
00161
00162
00163 extern(Windows)
00164 {
00165 const int WSADESCRIPTION_LEN = 256;
00166 const int WSASYS_STATUS_LEN = 128;
00167
00168 struct WSADATA
00169 {
00170 WORD wVersion;
00171 WORD wHighVersion;
00172 char szDescription[WSADESCRIPTION_LEN+1];
00173 char szSystemStatus[WSASYS_STATUS_LEN+1];
00174 ushort iMaxSockets;
00175 ushort iMaxUdpDg;
00176 char* lpVendorInfo;
00177 }
00178 alias WSADATA* LPWSADATA;
00179
00180
00181 const int IOCPARM_MASK = 0x7f;
00182 const int IOC_IN = cast(int)0x80000000;
00183 const int FIONBIO = cast(int) (IOC_IN | ((int.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126);
00184 const int SOL_SOCKET = 0xFFFF;
00185 const int SO_TYPE = 0x1008;
00186
00187
00188 int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
00189 int WSACleanup();
00190 socket_t socket(int af, int type, int protocol);
00191 int ioctlsocket(socket_t s, int cmd, uint* argp);
00192 int getsockopt(socket_t s, int level, int optname, char* optval, int* optlen);
00193 uint inet_addr(char* cp);
00194 int bind(socket_t s, sockaddr* name, int namelen);
00195 int connect(socket_t s, sockaddr* name, int namelen);
00196 int listen(socket_t s, int backlog);
00197 socket_t accept(socket_t s, sockaddr* addr, int* addrlen);
00198 int closesocket(socket_t s);
00199 int shutdown(socket_t s, int how);
00200 int getpeername(socket_t s, sockaddr* name, int* namelen);
00201 int getsockname(socket_t s, sockaddr* name, int* namelen);
00202 int send(socket_t s, void* buf, int len, int flags);
00203 int sendto(socket_t s, void* buf, int len, int flags, sockaddr* to, int tolen);
00204 int recv(socket_t s, void* buf, int len, int flags);
00205 int recvfrom(socket_t s, void* buf, int len, int flags, sockaddr* from, int* fromlen);
00206 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout);
00207
00208 int getsockopt(socket_t s, int level, int optname, void* optval, int* optlen);
00209 int setsockopt(socket_t s, int level, int optname, void* optval, int optlen);
00210 int gethostname(void* namebuffer, int buflen);
00211 char* inet_ntoa(uint ina);
00212 hostent* gethostbyname(char* name);
00213 hostent* gethostbyaddr(void* addr, int len, int type);
00214
00215
00216 const int WSAEWOULDBLOCK = 10035;
00217 const int WSAEINTR = 10004;
00218
00219 int WSAGetLastError();
00220 }
00221 }
00222 else version(BsdSockets)
00223 {
00224 extern(C)
00225 {
00226 const int F_GETFL = 3;
00227 const int F_SETFL = 4;
00228 const int O_NONBLOCK = 0x4000;
00229 const int SOL_SOCKET_D = 0xFFFF;
00230 alias SOL_SOCKET_D SOL_SOCKET;
00231 const int SO_TYPE = 0x1008;
00232
00233
00234 socket_t socket(int af, int type, int protocol);
00235 int fcntl(socket_t s, int f, ...);
00236 int getsockopt(socket_t s, int level, int optname, char* optval, int* optlen);
00237 uint inet_addr(char* cp);
00238 int bind(socket_t s, sockaddr* name, int namelen);
00239 int connect(socket_t s, sockaddr* name, int namelen);
00240 int listen(socket_t s, int backlog);
00241 socket_t accept(socket_t s, sockaddr* addr, int* addrlen);
00242 int close(socket_t s);
00243 int shutdown(socket_t s, int how);
00244 int getpeername(socket_t s, sockaddr* name, int* namelen);
00245 int getsockname(socket_t s, sockaddr* name, int* namelen);
00246 int send(socket_t s, void* buf, int len, int flags);
00247 int sendto(socket_t s, void* buf, int len, int flags, sockaddr* to, int tolen);
00248 int recv(socket_t s, void* buf, int len, int flags);
00249 int recvfrom(socket_t s, void* buf, int len, int flags, sockaddr* from, int* fromlen);
00250 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout);
00251 int getsockopt(socket_t s, int level, int optname, void* optval, int* optlen);
00252 int setsockopt(socket_t s, int level, int optname, void* optval, int optlen);
00253 int gethostname(void* namebuffer, int buflen);
00254 char* inet_ntoa(uint ina);
00255 hostent* gethostbyname(char* name);
00256 hostent* gethostbyaddr(void* addr, int len, int type);
00257
00258
00259 const int EINTR = 4;
00260 version (Posix)
00261 {
00262 const int EINPROGRESS = 115;
00263
00264 version (linux)
00265 private import std.c.linux.linux;
00266 else
00267 version (darwin)
00268 private import std.c.darwin.darwin;
00269 else
00270 static assert (0);
00271 }
00272 else
00273 {
00274 static assert(0);
00275 }
00276 }
00277 }
00278
00279 /+
00280 #ifdef INCLUDE_ALL_FOR_DOXYGEN
00281 +/
00282
00283
00284
00285
00286
00287
00288
00289 struct timeval
00290 {
00291 int tv_sec;
00292 int tv_usec;
00293 }
00294
00295
00296
00297 struct fd_set
00298 {
00299 }
00300
00301
00302 struct sockaddr
00303 {
00304 ushort sa_family;
00305 char[14] sa_data = [0];
00306 }
00307
00308
00309 struct hostent
00310 {
00311 char* h_name;
00312 char** h_aliases;
00313 version(Win32)
00314 {
00315 short h_addrtype;
00316 short h_length;
00317 }
00318 else version(BsdSockets)
00319 {
00320 int h_addrtype;
00321 int h_length;
00322 }
00323 char** h_addr_list;
00324
00325
00326 char* h_addr()
00327 {
00328 return h_addr_list[0];
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 version(BigEndian)
00340 {
00341 uint16_t htons(uint16_t x)
00342 {
00343 return x;
00344 }
00345
00346
00347 uint32_t htonl(uint32_t x)
00348 {
00349 return x;
00350 }
00351 }
00352 else version(LittleEndian)
00353 {
00354 import std.intrinsic;
00355
00356
00357 uint16_t htons(uint16_t x)
00358 {
00359 return (x >> 8) | (x << 8);
00360 }
00361
00362
00363 uint32_t htonl(uint32_t x)
00364 {
00365 return bswap(x);
00366 }
00367 }
00368 else
00369 {
00370 static assert(0);
00371 }
00372
00373
00374 uint16_t ntohs(uint16_t x)
00375 {
00376 return htons(x);
00377 }
00378
00379
00380 uint32_t ntohl(uint32_t x)
00381 {
00382 return htonl(x);
00383 }
00384
00385 /+
00386 #endif
00387 +/
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 public:
00398
00399
00400
00401
00402
00403
00404
00405 class HostException: IOException
00406 {
00407 this(char[] msg)
00408 {
00409 super(msg);
00410 }
00411 }
00412
00413
00414
00415
00416
00417
00418
00419 class SocketException: IOException
00420 {
00421 this(char[] msg)
00422 {
00423 super(msg);
00424 }
00425 }
00426
00427
00428
00429
00430
00431
00432
00433 class AddressException: SocketException
00434 {
00435 this(char[] msg)
00436 {
00437 super(msg);
00438 }
00439 }
00440
00441
00442
00443
00444
00445
00446
00447 class SocketAcceptException: SocketException
00448 {
00449 this(char[] msg)
00450 {
00451 super(msg);
00452 }
00453 }
00454
00455
00456
00457
00458
00459
00460
00461 static int lastError ()
00462 {
00463 version (Win32)
00464 {
00465 return WSAGetLastError();
00466 }
00467 version (Posix)
00468 {
00469 return getErrno();
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480 class Socket : Resource
00481 {
00482 private:
00483 socket_t sock;
00484 Socket.AddressFamily _family;
00485 static bool cancelled;
00486
00487 version(Win32)
00488 bit _blocking = false;
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 protected this(socket_t sock)
00499 {
00500
00501 set (sock);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511 protected void set (socket_t sock)
00512 {
00513 this.sock = sock;
00514
00515
00516 acquire();
00517 }
00518
00519
00520
00521
00522
00523
00524
00525 protected void reset ()
00526 {
00527 this.sock = INVALID_SOCKET;
00528 }
00529
00530
00531 public:
00532
00533
00534
00535
00536
00537
00538
00539 static bool isCancelled ()
00540 {
00541 return cancelled;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550 static void cancelAll (bool cancel)
00551 {
00552 cancelled = cancel;
00553 version (TraceLinux)
00554 {
00555 printf ("socket cancel status now set\n");
00556 }
00557 }
00558
00559
00560
00561
00562
00563
00564
00565 /+
00566 #ifdef INCLUDE_ALL_FOR_DOXYGEN
00567 +/
00568
00569 version (Win32)
00570 {
00571
00572
00573
00574
00575
00576 enum Option: int
00577 {
00578
00579 SO_DEBUG = 0x1,
00580
00581
00582 SO_BROADCAST = 0x20,
00583 SO_REUSEADDR = 0x4,
00584 SO_LINGER = 0x80,
00585 SO_DONTLINGER = ~(SO_LINGER),
00586 SO_OOBINLINE = 0x100,
00587 SO_SNDBUF = 0x1001,
00588 SO_RCVBUF = 0x1002,
00589 SO_ERROR = 0x1007,
00590
00591 SO_ACCEPTCONN = 0x2,
00592 SO_KEEPALIVE = 0x8,
00593 SO_DONTROUTE = 0x10,
00594 SO_TYPE = 0x1008,
00595
00596
00597 IP_MULTICAST_LOOP = 0x4,
00598 IP_ADD_MEMBERSHIP = 0x5,
00599 IP_DROP_MEMBERSHIP = 0x6,
00600 }
00601
00602
00603
00604
00605
00606
00607 union linger
00608 {
00609 struct {
00610 ushort l_onoff;
00611 ushort l_linger;
00612 };
00613 ushort[2] array;
00614 }
00615
00616
00617
00618
00619
00620
00621 enum OptionLevel
00622 {
00623 SOCKET = 0xFFFF,
00624 IP = 0,
00625 TCP = 6,
00626 UDP = 17,
00627 }
00628 }
00629
00630 version (BsdSockets)
00631 {
00632
00633
00634
00635
00636
00637
00638
00639 enum Option: int
00640 {
00641
00642 SO_DEBUG = 1,
00643 SO_BROADCAST = 6,
00644 SO_REUSEADDR = 2,
00645 SO_LINGER = 13,
00646 SO_DONTLINGER = ~(SO_LINGER),
00647 SO_OOBINLINE = 10,
00648 SO_SNDBUF = 7,
00649 SO_RCVBUF = 8,
00650 SO_ERROR = 4,
00651
00652 SO_ACCEPTCONN = 30,
00653 SO_KEEPALIVE = 9,
00654 SO_DONTROUTE = 5,
00655 SO_TYPE = 3,
00656
00657
00658 IP_MULTICAST_LOOP = 34,
00659 IP_ADD_MEMBERSHIP = 35,
00660 IP_DROP_MEMBERSHIP = 36,
00661 }
00662
00663
00664
00665
00666
00667
00668 union linger
00669 {
00670 struct {
00671 int l_onoff;
00672 int l_linger;
00673 };
00674 int[2] array;
00675 }
00676
00677
00678
00679
00680
00681
00682 enum OptionLevel
00683 {
00684 SOCKET = 1,
00685 IP = 0,
00686 TCP = 6,
00687 UDP = 17,
00688 }
00689 }
00690
00691
00692
00693
00694
00695
00696 enum Shutdown: int
00697 {
00698 RECEIVE = 0,
00699 SEND = 1,
00700 BOTH = 2,
00701 }
00702
00703
00704
00705
00706
00707
00708 enum Flags: int
00709 {
00710 NONE = 0,
00711 OOB = 0x1,
00712 PEEK = 0x02,
00713 DONTROUTE = 0x04,
00714 }
00715
00716
00717
00718
00719
00720
00721 enum Type: int
00722 {
00723 STREAM = 1,
00724 DGRAM = 2,
00725 RAW = 3,
00726 RDM = 4,
00727 SEQPACKET = 5,
00728 }
00729
00730
00731
00732
00733
00734
00735
00736 enum Protocol: int
00737 {
00738 IP = 0,
00739 ICMP = 1,
00740 IGMP = 2,
00741 GGP = 3,
00742 TCP = 6,
00743 PUP = 12,
00744 UDP = 17,
00745 IDP = 22,
00746 ND = 77,
00747 RAW = 255,
00748 MAX = 256,
00749 }
00750
00751
00752
00753
00754
00755
00756
00757 version(Win32)
00758 {
00759 enum AddressFamily: int
00760 {
00761 UNSPEC = 0,
00762 UNIX = 1,
00763 INET = 2,
00764 IPX = 6,
00765 APPLETALK = 16,
00766
00767 }
00768 }
00769 else version(BsdSockets)
00770 {
00771 enum AddressFamily: int
00772 {
00773 UNSPEC = 0,
00774 UNIX = 1,
00775 INET = 2,
00776 IPX = 4,
00777 APPLETALK = 5,
00778
00779 }
00780 }
00781
00782 /+
00783 #endif
00784 +/
00785
00786
00787
00788
00789
00790
00791
00792 this (Socket.AddressFamily af, Socket.Type type, Socket.Protocol protocol)
00793 {
00794 create (af, type, protocol);
00795
00796
00797 acquire();
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807 protected void create (Socket.AddressFamily af, Socket.Type type, Socket.Protocol protocol)
00808 {
00809 sock = socket (af, type, protocol);
00810 if(sock == sock.init)
00811 exception("Unable to create socket: ");
00812 _family = af;
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822 socket_t handle()
00823 {
00824 return sock;
00825 }
00826
00827
00828
00829
00830
00831
00832
00833 override char[] toString()
00834 {
00835 return "Socket";
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845 bit blocking()
00846 {
00847 version(Win32)
00848 {
00849 return _blocking;
00850 }
00851 else version(BsdSockets)
00852 {
00853 return !(fcntl(handle, F_GETFL, 0) & O_NONBLOCK);
00854 }
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864 void blocking(bit byes)
00865 {
00866 version(Win32)
00867 {
00868 uint num = !byes;
00869 if(SOCKET_ERROR == ioctlsocket(sock, FIONBIO, &num))
00870 goto err;
00871 _blocking = byes;
00872 }
00873 else version(BsdSockets)
00874 {
00875 int x = fcntl(handle, F_GETFL, 0);
00876 if(byes)
00877 x &= ~O_NONBLOCK;
00878 else
00879 x |= O_NONBLOCK;
00880 if(SOCKET_ERROR == fcntl(sock, F_SETFL, x))
00881 goto err;
00882 }
00883 return;
00884
00885 err:
00886 exception("Unable to set socket blocking: ");
00887 }
00888
00889
00890
00891
00892
00893
00894
00895 AddressFamily addressFamily()
00896 {
00897 return _family;
00898 }
00899
00900
00901
00902
00903
00904
00905
00906 bit isAlive()
00907 {
00908 int type, typesize = type.sizeof;
00909 return getsockopt (sock, SOL_SOCKET, SO_TYPE, cast(char*) &type, &typesize) != SOCKET_ERROR;
00910 }
00911
00912
00913
00914
00915
00916
00917
00918 void bind(Address addr)
00919 {
00920 if(SOCKET_ERROR == .bind (sock, addr.name(), addr.nameLen()))
00921 exception ("Unable to bind socket: ");
00922 }
00923
00924
00925
00926
00927
00928
00929
00930 void connect(Address to)
00931 {
00932 if(SOCKET_ERROR == .connect (sock, to.name(), to.nameLen()))
00933 {
00934 if(!blocking)
00935 {
00936 version(Win32)
00937 {
00938 if(WSAEWOULDBLOCK == WSAGetLastError())
00939 return;
00940 }
00941 else version (Posix)
00942 {
00943 if(EINPROGRESS == getErrno())
00944 return;
00945 }
00946 else
00947 {
00948 static assert(0);
00949 }
00950 }
00951 exception ("Unable to connect socket: ");
00952 }
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962 void listen(int backlog)
00963 {
00964 if(SOCKET_ERROR == .listen (sock, backlog))
00965 exception ("Unable to listen on socket: ");
00966 }
00967
00968
00969
00970
00971
00972
00973
00974 protected Socket createSocket (socket_t handle)
00975 {
00976 return new Socket (handle);
00977 }
00978
00979
00980
00981
00982
00983
00984 Socket accept()
00985 {
00986 socket_t newsock = .accept (sock, null, null);
00987 if(INVALID_SOCKET == newsock)
00988
00989
00990 {
00991 return null;
00992
00993 }
00994
00995
00996 Socket newSocket = createSocket (newsock);
00997
00998 version(Win32)
00999 newSocket._blocking = _blocking;
01000 newSocket._family = _family;
01001 return newSocket;
01002 }
01003
01004
01005
01006
01007
01008
01009
01010 void shutdown()
01011 {
01012 .shutdown (sock, cast(int) Shutdown.BOTH);
01013 }
01014
01015
01016
01017
01018
01019
01020 void shutdown(Socket.Shutdown how)
01021 {
01022 .shutdown (sock, cast(int)how);
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032 void setLingerPeriod (int period)
01033 {
01034 linger l;
01035
01036 l.l_onoff = 1;
01037 l.l_linger = period;
01038
01039 setOption (OptionLevel.SOCKET, Option.SO_LINGER, l.array);
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 void setAddressReuse (bool enabled)
01051 {
01052 int[1] x = enabled;
01053 setOption (OptionLevel.SOCKET, Option.SO_REUSEADDR, x);
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 bool setGroup (InternetAddress address, Socket.Option option)
01067 {
01068 struct ip_mreq
01069 {
01070 uint imr_multiaddr;
01071 uint imr_interface;
01072 };
01073
01074 ip_mreq mrq;
01075
01076 mrq.imr_interface = 0;
01077 mrq.imr_multiaddr = address.sin.sin_addr;
01078 return .setsockopt(handle(), OptionLevel.IP, option, &mrq, mrq.sizeof) != SOCKET_ERROR;
01079 }
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 override void closure ()
01092 {
01093 version (TraceLinux)
01094 {
01095 printf ("closing socket handle ...\n");
01096 }
01097 version(Win32)
01098 {
01099 .closesocket (sock);
01100 }
01101 else version(BsdSockets)
01102 {
01103 .close (sock);
01104 }
01105 sock = sock.init;
01106 version (TraceLinux)
01107 {
01108 printf ("socket handle closed\n");
01109 }
01110 }
01111
01112
01113
01114
01115
01116
01117
01118 private Address newFamilyObject ()
01119 {
01120 Address result;
01121 switch(_family)
01122 {
01123 case AddressFamily.INET:
01124 result = new InternetAddress;
01125 break;
01126
01127 default:
01128 result = new UnknownAddress;
01129 }
01130 return result;
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140 static char[] hostName ()
01141 {
01142 char[64] name;
01143
01144 if(SOCKET_ERROR == .gethostname (name, name.length))
01145 exception ("Unable to obtain host name: ");
01146 return name [0 .. std.string.strlen(name)].dup;
01147 }
01148
01149
01150
01151
01152
01153
01154
01155
01156 static uint hostAddress ()
01157 {
01158 InternetHost ih = new InternetHost;
01159
01160 char[] hostname = hostName();
01161 ih.getHostByName (hostname);
01162 assert (ih.addrList.length);
01163 return ih.addrList[0];
01164 }
01165
01166
01167
01168
01169
01170
01171
01172 Address remoteAddress ()
01173 {
01174 Address addr = newFamilyObject ();
01175 int nameLen = addr.nameLen ();
01176 if(SOCKET_ERROR == .getpeername (sock, addr.name(), &nameLen))
01177 exception ("Unable to obtain remote socket address: ");
01178 assert (addr.addressFamily() == _family);
01179 return addr;
01180 }
01181
01182
01183
01184
01185
01186
01187
01188 Address localAddress ()
01189 {
01190 Address addr = newFamilyObject ();
01191 int nameLen = addr.nameLen();
01192 if(SOCKET_ERROR == .getsockname (sock, addr.name(), &nameLen))
01193 exception ("Unable to obtain local socket address: ");
01194 assert (addr.addressFamily() == _family);
01195 return addr;
01196 }
01197
01198
01199
01200
01201
01202
01203
01204
01205 int send (void[] buf, Socket.Flags flags = Socket.Flags.NONE)
01206 {
01207 int sent = .send (sock, buf, buf.length, cast(int)flags);
01208 return sent;
01209 }
01210
01211
01212
01213
01214
01215
01216
01217
01218 int sendTo (void[] buf, Socket.Flags flags, Address to)
01219 {
01220 int sent = .sendto (sock, buf, buf.length, cast(int)flags, to.name(), to.nameLen());
01221 return sent;
01222 }
01223
01224
01225
01226
01227
01228
01229
01230
01231 int sendTo (void[] buf, Address to)
01232 {
01233 return sendTo (buf, Socket.Flags.NONE, to);
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243 int sendTo (void[] buf, Socket.Flags flags = Socket.Flags.NONE)
01244 {
01245 int sent = .sendto (sock, buf, buf.length, cast(int)flags, null, 0);
01246 return sent;
01247 }
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 int receive (void[] buf, Socket.Flags flags = Socket.Flags.NONE)
01258 {
01259 if(!buf.length)
01260 return 0;
01261 int read = .recv(sock, buf, buf.length, cast(int)flags);
01262 if (read == SOCKET_ERROR)
01263 exception ("Failed while receiving socket data: ");
01264
01265 return read;
01266 }
01267
01268
01269
01270
01271
01272
01273
01274
01275 int receiveFrom (void[] buf, Socket.Flags flags, out Address from)
01276 {
01277 if(!buf.length)
01278 return 0;
01279 version (TraceLinux)
01280 {
01281 printf ("executing recvFrom() \n");
01282 }
01283 from = newFamilyObject ();
01284 int nameLen = from.nameLen ();
01285 int read = .recvfrom (sock, buf, buf.length, cast(int)flags, from.name(), &nameLen);
01286 version (TraceLinux)
01287 {
01288 printf ("recvFrom returns %d\n", read);
01289 }
01290 if (read == SOCKET_ERROR)
01291 exception ("Failed while receiving socket data: ");
01292
01293 assert (from.addressFamily() == _family);
01294
01295 return read;
01296 }
01297
01298
01299
01300
01301
01302
01303
01304
01305 int receiveFrom (void[] buf, out Address from)
01306 {
01307 return receiveFrom (buf, Socket.Flags.NONE, from);
01308 }
01309
01310
01311
01312
01313
01314
01315
01316
01317 int receiveFrom (void[] buf, Socket.Flags flags)
01318 {
01319 if(!buf.length)
01320 return 0;
01321 int read = .recvfrom (sock, buf, buf.length, cast(int)flags, null, null);
01322 if (read == SOCKET_ERROR)
01323 exception ("Failed while receiving socket data: ");
01324
01325 return read;
01326 }
01327
01328
01329
01330
01331
01332
01333
01334
01335 int receiveFrom (void[] buf)
01336 {
01337 return receiveFrom (buf, Socket.Flags.NONE);
01338 }
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348 int getOption (Socket.OptionLevel level, Socket.Option option, void[] result)
01349 {
01350 int len = result.length;
01351 if(SOCKET_ERROR == .getsockopt (sock, cast(int)level, cast(int)option, result, &len))
01352 exception ("Unable to get socket option: ");
01353 return len;
01354 }
01355
01356
01357
01358
01359
01360
01361
01362 void setOption (Socket.OptionLevel level, Socket.Option option, void[] value)
01363 {
01364 if(SOCKET_ERROR == .setsockopt (sock, cast(int)level, cast(int)option, value, value.length))
01365 exception ("Unable to set socket option: ");
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375 protected static void exception (char[] msg)
01376 {
01377 msg ~= System.error (lastError);
01378 throw new SocketException (msg);
01379 }
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 static int select (SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, timeval* tv)
01397 in
01398 {
01399
01400 if(checkRead)
01401 {
01402 assert(checkRead !== checkWrite);
01403 assert(checkRead !== checkError);
01404 }
01405 if(checkWrite)
01406 {
01407 assert(checkWrite !== checkError);
01408 }
01409 }
01410 body
01411 {
01412 fd_set* fr, fw, fe;
01413
01414 version(Win32)
01415 {
01416
01417 fr = (checkRead && checkRead.count()) ? checkRead.toFd_set() : null;
01418 fw = (checkWrite && checkWrite.count()) ? checkWrite.toFd_set() : null;
01419 fe = (checkError && checkError.count()) ? checkError.toFd_set() : null;
01420 }
01421 else
01422 {
01423 fr = checkRead ? checkRead.toFd_set() : null;
01424 fw = checkWrite ? checkWrite.toFd_set() : null;
01425 fe = checkError ? checkError.toFd_set() : null;
01426 }
01427
01428 int result;
01429
01430
01431 while ((result = .select (socket_t.max - 1, fr, fw, fe, tv)) == -1)
01432 version(Win32)
01433 {
01434 if(WSAGetLastError() != WSAEINTR)
01435 break;
01436 }
01437 else version (Posix)
01438 {
01439 if(getErrno() != EINTR)
01440 break;
01441 }
01442 else
01443 {
01444 static assert(0);
01445 }
01446
01447
01448
01449
01450
01451
01452 return result;
01453 }
01454
01455
01456
01457
01458
01459
01460
01461 static int select (SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, int microseconds)
01462 {
01463 timeval tv;
01464 tv.tv_sec = 0;
01465 tv.tv_usec = microseconds;
01466 return select (checkRead, checkWrite, checkError, &tv);
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476 static int select (SocketSet checkRead, SocketSet checkWrite, SocketSet checkError)
01477 {
01478 return select (checkRead, checkWrite, checkError, null);
01479 }
01480
01481
01482
01483
01484
01485
01486
01487 /+
01488 bit poll (events)
01489 {
01490 int WSAEventSelect(socket_t s, WSAEVENT hEventObject, int lNetworkEvents);
01491 int poll(pollfd* fds, int nfds, int timeout);
01492 }
01493 +/
01494
01495
01496 }
01497
01498
01499
01500
01501
01502
01503
01504
01505 abstract class Address
01506 {
01507 protected sockaddr* name();
01508 protected int nameLen();
01509 Socket.AddressFamily addressFamily();
01510 char[] toString();
01511 }
01512
01513
01514
01515
01516
01517
01518
01519 class UnknownAddress: Address
01520 {
01521 protected:
01522 sockaddr sa;
01523
01524
01525
01526
01527
01528
01529
01530 sockaddr* name()
01531 {
01532 return &sa;
01533 }
01534
01535
01536
01537
01538
01539
01540
01541 int nameLen()
01542 {
01543 return sa.sizeof;
01544 }
01545
01546
01547 public:
01548
01549
01550
01551
01552
01553 Socket.AddressFamily addressFamily()
01554 {
01555 return cast(Socket.AddressFamily)sa.sa_family;
01556 }
01557
01558
01559
01560
01561
01562
01563
01564 char[] toString()
01565 {
01566 return "Unknown";
01567 }
01568 }
01569
01570
01571
01572
01573
01574
01575
01576 class InternetHost
01577 {
01578 char[] name;
01579 char[][] aliases;
01580 uint[] addrList;
01581
01582
01583
01584
01585
01586
01587
01588 protected void validHostent(hostent* he)
01589 {
01590 if(he.h_addrtype != cast(int)Socket.AddressFamily.INET || he.h_length != 4)
01591 throw new HostException("Address family mismatch.");
01592 }
01593
01594
01595
01596
01597
01598
01599
01600 void populate(hostent* he)
01601 {
01602 int i;
01603 char* p;
01604
01605 name = std.string.toString(he.h_name);
01606
01607 for(i = 0;; i++)
01608 {
01609 p = he.h_aliases[i];
01610 if(!p)
01611 break;
01612 }
01613
01614 if(i)
01615 {
01616 aliases = new char[][i];
01617 for(i = 0; i != aliases.length; i++)
01618 {
01619 aliases[i] = std.string.toString(he.h_aliases[i]);
01620 }
01621 }
01622 else
01623 {
01624 aliases = null;
01625 }
01626
01627 for(i = 0;; i++)
01628 {
01629 p = he.h_addr_list[i];
01630 if(!p)
01631 break;
01632 }
01633
01634 if(i)
01635 {
01636 addrList = new uint[i];
01637 for(i = 0; i != addrList.length; i++)
01638 {
01639 addrList[i] = ntohl(*(cast(uint*)he.h_addr_list[i]));
01640 }
01641 }
01642 else
01643 {
01644 addrList = null;
01645 }
01646 }
01647
01648
01649
01650
01651
01652
01653
01654 bit getHostByName(char[] name)
01655 {
01656 hostent* he = gethostbyname(std.string.toStringz(name));
01657 if(!he)
01658 return false;
01659 validHostent(he);
01660 populate(he);
01661 return true;
01662 }
01663
01664
01665
01666
01667
01668
01669
01670 bit getHostByAddr(uint addr)
01671 {
01672 uint x = htonl(addr);
01673 hostent* he = gethostbyaddr(&x, 4, cast(int)Socket.AddressFamily.INET);
01674 if(!he)
01675 return false;
01676 validHostent(he);
01677 populate(he);
01678 return true;
01679 }
01680
01681
01682
01683
01684
01685
01686
01687
01688 bit getHostByAddr(char[] addr)
01689 {
01690 uint x = inet_addr(std.string.toStringz(addr));
01691 hostent* he = gethostbyaddr(&x, 4, cast(int)Socket.AddressFamily.INET);
01692 if(!he)
01693 return false;
01694 validHostent(he);
01695 populate(he);
01696 return true;
01697 }
01698 }
01699
01700
01701 unittest
01702 {
01703 InternetHost ih = new InternetHost;
01704 assert(ih.addrList.length);
01705 InternetAddress ia = new InternetAddress(ih.addrList[0], InternetAddress.PORT_ANY);
01706 printf("IP address = %.*s\nname = %.*s\n", ia.toAddrString(), ih.name);
01707 foreach(int i, char[] s; ih.aliases)
01708 {
01709 printf("aliases[%d] = %.*s\n", i, s);
01710 }
01711
01712 printf("---\n");
01713
01714 assert(ih.getHostByAddr(ih.addrList[0]));
01715 printf("name = %.*s\n", ih.name);
01716 foreach(int i, char[] s; ih.aliases)
01717 {
01718 printf("aliases[%d] = %.*s\n", i, s);
01719 }
01720 }
01721
01722
01723
01724
01725
01726
01727
01728 class InternetAddress: Address
01729 {
01730 /+
01731 #ifdef INCLUDE_ALL_FOR_DOXYGEN
01732 +/
01733 protected:
01734
01735
01736
01737
01738
01739 struct sockaddr_in
01740 {
01741 ushort sin_family = cast(ushort)Socket.AddressFamily.INET;
01742 ushort sin_port;
01743 uint sin_addr;
01744 char[8] sin_zero = [0];
01745 }
01746 /+
01747 #endif
01748 +/
01749
01750 sockaddr_in sin;
01751
01752
01753
01754
01755
01756
01757
01758 sockaddr* name()
01759 {
01760 return cast(sockaddr*)&sin;
01761 }
01762
01763
01764
01765
01766
01767
01768
01769 int nameLen()
01770 {
01771 return sin.sizeof;
01772 }
01773
01774
01775
01776
01777
01778
01779
01780 this()
01781 {
01782 }
01783
01784
01785 public:
01786 const uint ADDR_ANY = 0;
01787 const uint ADDR_NONE = cast(uint)-1;
01788 const ushort PORT_ANY = 0;
01789
01790
01791
01792
01793
01794
01795
01796 Socket.AddressFamily addressFamily()
01797 {
01798 return Socket.AddressFamily.INET;
01799 }
01800
01801
01802
01803
01804
01805
01806
01807 ushort port()
01808 {
01809 return ntohs(sin.sin_port);
01810 }
01811
01812
01813
01814
01815
01816
01817
01818 uint addr()
01819 {
01820 return ntohl(sin.sin_addr);
01821 }
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 this(char[] addr, ushort port = PORT_ANY)
01832 {
01833 uint uiaddr = parse(addr);
01834 if(ADDR_NONE == uiaddr)
01835 {
01836 InternetHost ih = new InternetHost;
01837 if(!ih.getHostByName(addr))
01838 throw new AddressException("Invalid internet address '"~addr~"'");
01839 uiaddr = ih.addrList[0];
01840 }
01841 sin.sin_addr = htonl(uiaddr);
01842 sin.sin_port = htons(port);
01843 }
01844
01845
01846
01847
01848
01849
01850
01851 this(uint addr, ushort port)
01852 {
01853 sin.sin_addr = htonl(addr);
01854 sin.sin_port = htons(port);
01855 }
01856
01857
01858
01859
01860
01861
01862
01863 this(ushort port)
01864 {
01865 sin.sin_addr = 0;
01866 sin.sin_port = htons(port);
01867 }
01868
01869
01870
01871
01872
01873
01874
01875 char[] toAddrString()
01876 {
01877 return std.string.toString(inet_ntoa(sin.sin_addr)).dup;
01878 }
01879
01880
01881
01882
01883
01884
01885
01886 char[] toPortString()
01887 {
01888 return std.string.toString(port());
01889 }
01890
01891
01892
01893
01894
01895
01896
01897 char[] toString()
01898 {
01899 return toAddrString() ~ ":" ~ toPortString();
01900 }
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910 static uint parse(char[] addr)
01911 {
01912 return ntohl(inet_addr(std.string.toStringz(addr)));
01913 }
01914 }
01915
01916
01917 unittest
01918 {
01919 InternetAddress ia = new InternetAddress("63.105.9.61", 80);
01920 assert(ia.toString() == "63.105.9.61:80");
01921 }
01922
01923
01924
01925
01926
01927
01928
01929
01930 class SocketSet
01931 {
01932 private:
01933 uint nbytes;
01934 byte* buf;
01935
01936
01937 version(Win32)
01938 {
01939 uint count()
01940 {
01941 return *(cast(uint*)buf);
01942 }
01943
01944
01945 void count(int setter)
01946 {
01947 *(cast(uint*)buf) = setter;
01948 }
01949
01950
01951 socket_t* first()
01952 {
01953 return cast(socket_t*)(buf + uint.sizeof);
01954 }
01955 }
01956 else version (Posix)
01957 {
01958 import std.intrinsic;
01959
01960
01961 uint nfdbits;
01962
01963
01964 uint fdelt(socket_t s)
01965 {
01966 return cast(uint)s / nfdbits;
01967 }
01968
01969
01970 uint fdmask(socket_t s)
01971 {
01972 return 1 << cast(uint)s % nfdbits;
01973 }
01974
01975
01976 uint* first()
01977 {
01978 return cast(uint*)buf;
01979 }
01980 }
01981
01982
01983 public:
01984
01985
01986
01987
01988
01989 this(uint max)
01990 {
01991 version(Win32)
01992 {
01993 nbytes = max * socket_t.sizeof;
01994 buf = new byte[nbytes + uint.sizeof];
01995 count = 0;
01996 }
01997 else version (Posix)
01998 {
01999 if(max <= 32)
02000 nbytes = 32 * uint.sizeof;
02001 else
02002 nbytes = max * uint.sizeof;
02003 buf = new byte[nbytes];
02004 nfdbits = nbytes * 8;
02005
02006 }
02007 else
02008 {
02009 static assert(0);
02010 }
02011 }
02012
02013
02014
02015
02016
02017
02018
02019 this()
02020 {
02021 version(Win32)
02022 {
02023 this(64);
02024 }
02025 else version (Posix)
02026 {
02027 this(32);
02028 }
02029 else
02030 {
02031 static assert(0);
02032 }
02033 }
02034
02035
02036
02037
02038
02039
02040
02041 void reset()
02042 {
02043 version(Win32)
02044 {
02045 count = 0;
02046 }
02047 else version (Posix)
02048 {
02049 buf[0 .. nbytes] = 0;
02050 }
02051 else
02052 {
02053 static assert(0);
02054 }
02055 }
02056
02057
02058
02059
02060
02061
02062
02063 void add(socket_t s)
02064 in
02065 {
02066 version(Win32)
02067 {
02068 assert(count < max);
02069 }
02070 }
02071 body
02072 {
02073 version(Win32)
02074 {
02075 uint c = count;
02076 first[c] = s;
02077 count = c + 1;
02078 }
02079 else version (Posix)
02080 {
02081 bts(cast(uint*)&first[fdelt(s)], cast(uint)s % nfdbits);
02082 }
02083 else
02084 {
02085 static assert(0);
02086 }
02087 }
02088
02089
02090
02091
02092
02093
02094
02095 void add(Socket s)
02096 {
02097 add(s.sock);
02098 }
02099
02100
02101
02102
02103
02104
02105
02106 void remove(socket_t s)
02107 {
02108 version(Win32)
02109 {
02110 uint c = count;
02111 socket_t* start = first;
02112 socket_t* stop = start + c;
02113
02114 for(; start != stop; start++)
02115 {
02116 if(*start == s)
02117 goto found;
02118 }
02119 return;
02120
02121 found:
02122 for(++start; start != stop; start++)
02123 {
02124 *(start - 1) = *start;
02125 }
02126
02127 count = c - 1;
02128 }
02129 else version (Posix)
02130 {
02131 btr(cast(uint*)&first[fdelt(s)], cast(uint)s % nfdbits);
02132 }
02133 else
02134 {
02135 static assert(0);
02136 }
02137 }
02138
02139
02140
02141
02142
02143
02144
02145 void remove(Socket s)
02146 {
02147 remove(s.sock);
02148 }
02149
02150
02151
02152
02153
02154
02155
02156 int isSet(socket_t s)
02157 {
02158 version(Win32)
02159 {
02160 socket_t* start = first;
02161 socket_t* stop = start + count;
02162
02163 for(; start != stop; start++)
02164 {
02165 if(*start == s)
02166 return true;
02167 }
02168 return false;
02169 }
02170 else version (Posix)
02171 {
02172
02173 int index = cast(uint)s % nfdbits;
02174 return (cast(uint*)&first[fdelt(s)])[index / (uint.sizeof*8)] & (1 << (index & ((uint.sizeof*8) - 1)));
02175 }
02176 else
02177 {
02178 static assert(0);
02179 }
02180 }
02181
02182
02183
02184
02185
02186
02187
02188 int isSet(Socket s)
02189 {
02190 return isSet(s.sock);
02191 }
02192
02193
02194
02195
02196
02197
02198
02199
02200 uint max()
02201 {
02202 return nbytes / socket_t.sizeof;
02203 }
02204
02205
02206
02207
02208
02209
02210
02211 fd_set* toFd_set()
02212 {
02213 return cast(fd_set*)buf;
02214 }
02215 }
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229 interface IListener
02230 {
02231
02232
02233
02234
02235
02236
02237
02238 void cancel ();
02239 }
02240
02241
02242
02243
02244
02245
02246 interface ISocketReader
02247 {
02248
02249
02250
02251
02252
02253
02254
02255 int read (IBuffer buffer);
02256 }
02257
02258
02259