5 // Created by Chaz McGarvey on 2/1/05.
6 // Copyright 2005 Chaz McGarvey. All rights reserved.
10 * MySocket is my 24 hour hackjob. There are other classes which would have
11 * done a better job, but I found them to be too slow. This class wraps
12 * around BSD sockets directly. It uses two threads for both asynchronous
13 * reads and writes. Performance still isn't spectacular... I measure about
14 * 58 MB/s average when transfering to localhost.
15 * The way the old The Cheat did networking was by spawning a new thread for
16 * each connection (for both serving and receiving). I thought that this way
17 * would be more efficient, but the old way is noticeably faster. I may go
18 * back to that way eventually, after all it isn't that many threads.
21 #import <Cocoa/Cocoa.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
37 * This class has a few limitations which may not be obvious. First, it will
38 * only send back delegate methods on the Main thread, not necessarily the
39 * same thread used to create the socket. There is no way to time out a read
40 * or write action. There is no way to just read "all" data possible; you
41 * must specify how much data to receive.
45 @interface MySocket
: NSObject
49 NSMutableArray
*_readQueue
;
50 NSMutableArray
*_writeQueue
;
51 NSMutableData
*_unclaimedData
;
52 NSRecursiveLock
*_readLock
;
53 NSRecursiveLock
*_writeLock
;
57 unsigned _bytesWritten
;
58 NSTimeInterval _startTime
;
60 unsigned _lastBytesRead
;
61 unsigned _lastBytesWritten
;
62 NSTimeInterval _lastBytesReadTime
;
63 NSTimeInterval _lastBytesWrittenTime
;
69 - (id
)initWithDelegate
:(id
)delegate
;
71 /* CONNECTING/ACCEPTING */
72 - (BOOL
)connectToHost
:(NSString
*)host port
:(int)port
;
73 - (BOOL
)connectToAddress
:(const struct sockaddr
*)addr length
:(unsigned)addrLen
;
74 - (BOOL
)connectToAddressWithData
:(NSData
*)addr
;
75 - (BOOL
)listenOnPort
:(int)port
;
76 // returns YES on success
80 // the disconnect delegate method will NOT be called.
81 // it is only called when the socket is disconnect by remote or by error.
82 // absolutely NO delegate methods are sent after this (until reconnecting).
84 /* READING & WRITING */
85 - (void)readDataToLength
:(unsigned)len tag
:(int)tag
;
86 - (void)writeData
:(NSData
*)data tag
:(int)tag
;
87 - (void)writeBytes
:(void const *)bytes length
:(unsigned)len tag
:(int)tag
;
88 /* Nope, there is no way to time out a request. */
91 - (unsigned)bytesRead
;
92 - (unsigned)bytesWritten
;
93 /* the above accessors can be accessed after the socket is disconnected to get
94 the grand total amount of traffic passed through the socket. */
95 - (NSTimeInterval
)timeConnected
;
96 - (double)readSpeed
; // bytes/sec
97 - (double)writeSpeed
; // bytes/sec
98 /* These speeds are averaged out using the last time these methods were called.
99 The more often you call these methods the more accurate they will be. */
101 - (NSString
*)localHost
;
103 - (NSString
*)remoteHost
;
110 + (NSData
*)addressWithHost
:(NSString
*)host port
:(int)port
;
114 - (void)setDelegate
:(id
)delegate
;
119 @interface
NSObject ( MySocketDelegate
)
121 /* DELEGATE METHODS */
122 - (void)socketDidDisconnect
:(MySocket
*)mySocket
;
123 - (void)socket
:(MySocket
*)mySocket didAcceptSocket
:(MySocket
*)newSocket
;
124 - (void)socket
:(MySocket
*)mySocket didReadData
:(NSData
*)theData tag
:(int)tag
;
125 - (void)socket
:(MySocket
*)mySocket didWriteDataWithTag
:(int)tag
;