Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

140 lines (110 sloc) 4.246 kB
* The Cheat - The legendary universal game trainer for Mac OS X.
* Copyright (c) 2003-2011, Charles McGarvey et al.
* Distributable under the terms and conditions of the 2-clause BSD
* license; see the file COPYING for the legal text of the license.
* MySocket is my 24 hour hackjob. There are other classes which would have
* done a better job, but I found them to be too slow. This class wraps
* around BSD sockets directly. It uses two threads for both asynchronous
* reads and writes. Performance still isn't spectacular... I measure about
* 58 MB/s average when transfering to localhost.
* The way the old The Cheat did networking was by spawning a new thread for
* each connection (for both serving and receiving). I thought that this way
* would be more efficient, but the old way is noticeably faster. I may go
* back to that way eventually, after all it isn't that many threads.
* June 21 2005 - Chaz
* I have written a much more robust socket wrapper for another project that
* could be re-emplemented into The Cheat. It is cleaner code and has very
* nice statistics tracking features. I'm going on my mission tomorrow. This
* will have to wait two years or so. ;)
#import <Cocoa/Cocoa.h>
#import "ChazLog.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <string.h>
* This class has a few limitations which may not be obvious. First, it will
* only send back delegate methods on the Main thread, not necessarily the
* same thread used to create the socket. There is no way to time out a read
* or write action. There is no way to just read "all" data possible; you
* must specify how much data to receive.
@interface MySocket : NSObject
int _sockfd;
NSMutableArray *_readQueue;
NSMutableArray *_writeQueue;
NSMutableData *_unclaimedData;
NSRecursiveLock *_readLock;
NSRecursiveLock *_writeLock;
unsigned _flags;
unsigned _bytesRead;
unsigned _bytesWritten;
NSTimeInterval _startTime;
unsigned _lastBytesRead;
unsigned _lastBytesWritten;
NSTimeInterval _lastBytesReadTime;
NSTimeInterval _lastBytesWrittenTime;
id _delegate;
- (id)initWithDelegate:(id)delegate;
- (BOOL)connectToHost:(NSString *)host port:(int)port;
- (BOOL)connectToAddress:(const struct sockaddr *)addr length:(unsigned)addrLen;
- (BOOL)connectToAddressWithData:(NSData *)addr;
- (BOOL)listenOnPort:(int)port;
// returns YES on success
- (void)disconnect;
// the disconnect delegate method will NOT be called.
// it is only called when the socket is disconnect by remote or by error.
// absolutely NO delegate methods are sent after this (until reconnecting).
- (void)readDataToLength:(unsigned)len tag:(int)tag;
- (void)writeData:(NSData *)data tag:(int)tag;
- (void)writeBytes:(void const *)bytes length:(unsigned)len tag:(int)tag;
/* Nope, there is no way to time out a request. */
- (unsigned)bytesRead;
- (unsigned)bytesWritten;
/* the above accessors can be accessed after the socket is disconnected to get
the grand total amount of traffic passed through the socket. */
- (NSTimeInterval)timeConnected;
- (double)readSpeed; // bytes/sec
- (double)writeSpeed; // bytes/sec
/* These speeds are averaged out using the last time these methods were called.
The more often you call these methods the more accurate they will be. */
- (NSString *)localHost;
- (int)localPort;
- (NSString *)remoteHost;
- (int)remotePort;
- (BOOL)isConnected;
- (BOOL)isListener;
+ (NSData *)addressWithHost:(NSString *)host port:(int)port;
- (id)delegate;
- (void)setDelegate:(id)delegate;
@interface NSObject ( MySocketDelegate )
- (void)socketDidDisconnect:(MySocket *)mySocket;
- (void)socket:(MySocket *)mySocket didAcceptSocket:(MySocket *)newSocket;
- (void)socket:(MySocket *)mySocket didReadData:(NSData *)theData tag:(int)tag;
- (void)socket:(MySocket *)mySocket didWriteDataWithTag:(int)tag;
Jump to Line
Something went wrong with that request. Please try again.