2 // **********************************************************************
3 // The Cheat - A universal game cheater for Mac OS X
4 // (C) 2003-2005 Chaz McGarvey (BrokenZipper)
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 1, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * MySocket is my 24 hour hackjob. There are other classes which would have
24 * done a better job, but I found them to be too slow. This class wraps
25 * around BSD sockets directly. It uses two threads for both asynchronous
26 * reads and writes. Performance still isn't spectacular... I measure about
27 * 58 MB/s average when transfering to localhost.
28 * The way the old The Cheat did networking was by spawning a new thread for
29 * each connection (for both serving and receiving). I thought that this way
30 * would be more efficient, but the old way is noticeably faster. I may go
31 * back to that way eventually, after all it isn't that many threads.
36 * I have written a much more robust socket wrapper for another project that
37 * could be re-emplemented into The Cheat. It is cleaner code and has very
38 * nice statistics tracking features. I'm going on my mission tomorrow. This
39 * will have to wait two years or so. ;)
42 #import <Cocoa/Cocoa.h>
46 #include <sys/types.h>
47 #include <sys/socket.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
58 * This class has a few limitations which may not be obvious. First, it will
59 * only send back delegate methods on the Main thread, not necessarily the
60 * same thread used to create the socket. There is no way to time out a read
61 * or write action. There is no way to just read "all" data possible; you
62 * must specify how much data to receive.
66 @interface MySocket
: NSObject
70 NSMutableArray
*_readQueue
;
71 NSMutableArray
*_writeQueue
;
72 NSMutableData
*_unclaimedData
;
73 NSRecursiveLock
*_readLock
;
74 NSRecursiveLock
*_writeLock
;
78 unsigned _bytesWritten
;
79 NSTimeInterval _startTime
;
81 unsigned _lastBytesRead
;
82 unsigned _lastBytesWritten
;
83 NSTimeInterval _lastBytesReadTime
;
84 NSTimeInterval _lastBytesWrittenTime
;
90 - (id
)initWithDelegate
:(id
)delegate
;
92 /* CONNECTING/ACCEPTING */
93 - (BOOL
)connectToHost
:(NSString
*)host port
:(int)port
;
94 - (BOOL
)connectToAddress
:(const struct sockaddr
*)addr length
:(unsigned)addrLen
;
95 - (BOOL
)connectToAddressWithData
:(NSData
*)addr
;
96 - (BOOL
)listenOnPort
:(int)port
;
97 // returns YES on success
101 // the disconnect delegate method will NOT be called.
102 // it is only called when the socket is disconnect by remote or by error.
103 // absolutely NO delegate methods are sent after this (until reconnecting).
105 /* READING & WRITING */
106 - (void)readDataToLength
:(unsigned)len tag
:(int)tag
;
107 - (void)writeData
:(NSData
*)data tag
:(int)tag
;
108 - (void)writeBytes
:(void const *)bytes length
:(unsigned)len tag
:(int)tag
;
109 /* Nope, there is no way to time out a request. */
112 - (unsigned)bytesRead
;
113 - (unsigned)bytesWritten
;
114 /* the above accessors can be accessed after the socket is disconnected to get
115 the grand total amount of traffic passed through the socket. */
116 - (NSTimeInterval
)timeConnected
;
117 - (double)readSpeed
; // bytes/sec
118 - (double)writeSpeed
; // bytes/sec
119 /* These speeds are averaged out using the last time these methods were called.
120 The more often you call these methods the more accurate they will be. */
122 - (NSString
*)localHost
;
124 - (NSString
*)remoteHost
;
131 + (NSData
*)addressWithHost
:(NSString
*)host port
:(int)port
;
135 - (void)setDelegate
:(id
)delegate
;
140 @interface
NSObject ( MySocketDelegate
)
142 /* DELEGATE METHODS */
143 - (void)socketDidDisconnect
:(MySocket
*)mySocket
;
144 - (void)socket
:(MySocket
*)mySocket didAcceptSocket
:(MySocket
*)newSocket
;
145 - (void)socket
:(MySocket
*)mySocket didReadData
:(NSData
*)theData tag
:(int)tag
;
146 - (void)socket
:(MySocket
*)mySocket didWriteDataWithTag
:(int)tag
;