3 * The Cheat - The legendary universal game trainer for Mac OS X.
4 * http://www.dogcows.com/chaz/wiki/TheCheat
6 * Copyright (c) 2003-2010, Charles McGarvey et al.
8 * Distributable under the terms and conditions of the 2-clause BSD
9 * license; see the file COPYING for the legal text of the license.
14 * MySocket is my 24 hour hackjob. There are other classes which would have
15 * done a better job, but I found them to be too slow. This class wraps
16 * around BSD sockets directly. It uses two threads for both asynchronous
17 * reads and writes. Performance still isn't spectacular... I measure about
18 * 58 MB/s average when transfering to localhost.
19 * The way the old The Cheat did networking was by spawning a new thread for
20 * each connection (for both serving and receiving). I thought that this way
21 * would be more efficient, but the old way is noticeably faster. I may go
22 * back to that way eventually, after all it isn't that many threads.
27 * I have written a much more robust socket wrapper for another project that
28 * could be re-emplemented into The Cheat. It is cleaner code and has very
29 * nice statistics tracking features. I'm going on my mission tomorrow. This
30 * will have to wait two years or so. ;)
33 #import <Cocoa/Cocoa.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
49 * This class has a few limitations which may not be obvious. First, it will
50 * only send back delegate methods on the Main thread, not necessarily the
51 * same thread used to create the socket. There is no way to time out a read
52 * or write action. There is no way to just read "all" data possible; you
53 * must specify how much data to receive.
57 @interface MySocket
: NSObject
61 NSMutableArray
*_readQueue
;
62 NSMutableArray
*_writeQueue
;
63 NSMutableData
*_unclaimedData
;
64 NSRecursiveLock
*_readLock
;
65 NSRecursiveLock
*_writeLock
;
69 unsigned _bytesWritten
;
70 NSTimeInterval _startTime
;
72 unsigned _lastBytesRead
;
73 unsigned _lastBytesWritten
;
74 NSTimeInterval _lastBytesReadTime
;
75 NSTimeInterval _lastBytesWrittenTime
;
81 - (id
)initWithDelegate
:(id
)delegate
;
83 /* CONNECTING/ACCEPTING */
84 - (BOOL
)connectToHost
:(NSString
*)host port
:(int)port
;
85 - (BOOL
)connectToAddress
:(const struct sockaddr
*)addr length
:(unsigned)addrLen
;
86 - (BOOL
)connectToAddressWithData
:(NSData
*)addr
;
87 - (BOOL
)listenOnPort
:(int)port
;
88 // returns YES on success
92 // the disconnect delegate method will NOT be called.
93 // it is only called when the socket is disconnect by remote or by error.
94 // absolutely NO delegate methods are sent after this (until reconnecting).
96 /* READING & WRITING */
97 - (void)readDataToLength
:(unsigned)len tag
:(int)tag
;
98 - (void)writeData
:(NSData
*)data tag
:(int)tag
;
99 - (void)writeBytes
:(void const *)bytes length
:(unsigned)len tag
:(int)tag
;
100 /* Nope, there is no way to time out a request. */
103 - (unsigned)bytesRead
;
104 - (unsigned)bytesWritten
;
105 /* the above accessors can be accessed after the socket is disconnected to get
106 the grand total amount of traffic passed through the socket. */
107 - (NSTimeInterval
)timeConnected
;
108 - (double)readSpeed
; // bytes/sec
109 - (double)writeSpeed
; // bytes/sec
110 /* These speeds are averaged out using the last time these methods were called.
111 The more often you call these methods the more accurate they will be. */
113 - (NSString
*)localHost
;
115 - (NSString
*)remoteHost
;
122 + (NSData
*)addressWithHost
:(NSString
*)host port
:(int)port
;
126 - (void)setDelegate
:(id
)delegate
;
131 @interface
NSObject ( MySocketDelegate
)
133 /* DELEGATE METHODS */
134 - (void)socketDidDisconnect
:(MySocket
*)mySocket
;
135 - (void)socket
:(MySocket
*)mySocket didAcceptSocket
:(MySocket
*)newSocket
;
136 - (void)socket
:(MySocket
*)mySocket didReadData
:(NSData
*)theData tag
:(int)tag
;
137 - (void)socket
:(MySocket
*)mySocket didWriteDataWithTag
:(int)tag
;