/Volumes/Plantain/MyDocuments/Projects/MacTrek/MacTrek/Comm/ServerReaderUdp.m

00001 //
00002 //  ServerReaderUdp.m
00003 //  MacTrek
00004 //
00005 //  Created by Aqua on 06/05/2006.
00006 //  Copyright 2006 __MyCompanyName__. All rights reserved.
00007 //
00008 
00009 #import "ServerReaderUdp.h"
00010 
00011 
00012 @implementation ServerReaderUdp
00013 
00014 ONUDPSocket *udpSocket;
00015 
00016 - (id) init {
00017     self = [super init];
00018     if (self != nil) {
00019         udpSocket = nil; // very bad if it stays that way
00020         udpStats = nil;
00021     }
00022     return self;
00023 }
00024 
00025 - (id)initWithUniverse:(Universe*)newUniverse communication:(Communication*)comm socket:(ONUDPSocket *)socket udpStats:(UdpStats*)stats{
00026     self = [self initWithUniverse:newUniverse communication:comm];
00027     if (self != nil) {
00028         udpStats = stats;
00029         udpSocket = socket;
00030     }
00031     return self;
00032 }
00033 
00034 - (void) close {
00035     [udpSocket release];
00036     udpSocket = nil;
00037 }
00038 
00039 -(UdpStats*)udpStats {
00040     return udpStats;
00041 }
00042 
00043 - (NSData *) doRead {
00044     // read what ever is there max 1300 bytes
00045     // needs to be retained/released after processing !
00046     NSMutableData *data = [[NSMutableData dataWithLength: SRV_UDP_MAX_DATA_LENGTH] autorelease];
00047     // Have to set the data to its maximum length.  Otherwise,
00048     // when we come around this loop multiple times, the setLength:
00049     // below might be lengthening the data which would cause NSData
00050     // to zero out all of the bytes between the old length and the
00051     // new length.
00052     [data setLength: SRV_UDP_MAX_DATA_LENGTH];
00053     // try to read
00054     @try {        
00055         int length = [udpSocket readBytes: SRV_UDP_MAX_DATA_LENGTH
00056                                intoBuffer: [data mutableBytes]];
00057         [data setLength: length];    
00058     }
00059     @catch (NSException * e) {
00060         NSLog(@"ServerReaderUdp.doRead: Timed out waiting for UDP response from server");
00061         // error, switch to TCP just like when the server asks us to
00062         [communication setCommMode: COMM_TCP];
00063         [communication setCommStatus: STAT_CONNECTED];
00064         NSLog(@"ServerReaderUdp.doRead: Should connected to server's TCP port");
00065         [notificationCenter postNotificationName:@"SP_UDP_SWITCHED_TO_TCP" object:self userInfo:nil];
00066         
00067         return nil;
00068     }
00069     
00070     // debug
00071     NSLog([NSString stringWithFormat: @"ServerReaderUpd.doRead got packet from %@:%d:\n", 
00072         [udpSocket remoteAddressHost], [udpSocket remoteAddressPort]]);
00073     
00074     return data;
00075 }
00076 
00077 - (bool) handlePacket:(int)ptype withSize:(int)size inBuffer:(char *)buffer {
00078 
00079     [communication increasePacketsReceived];
00080     return [super handlePacket:ptype withSize:size inBuffer:buffer];
00081 }
00082 
00083 
00084 - (void) handleSequence:(char *) buffer {
00085     [udpStats increaseUdpTotalBy:1];
00086     [udpStats increaseRecentCountBy:1];
00087     
00088     // update percent display every 256 updates (~50 seconds usually)
00089     if (([udpStats udpTotal] & 0xFF) == 0) {
00090         [notificationCenter postNotificationName:@"SRU_UDP_STATS_CHANGED" 
00091                                           object:self userInfo:udpStats];
00092     }
00093     
00094     // it's in my parent but not declared..... 
00095     // thus a warning
00096     int new_sequence = shortFromPacket(buffer, 2);
00097     
00098     if ([udpStats sequence] > 65000 && new_sequence < 1000) {
00099         // we rolled, set new_sequence = 65536 + sequence and accept it
00100         [udpStats setSequence: (([udpStats sequence] + 65536) & 0xFFFF0000) | new_sequence];
00101     }
00102     else {
00103         // adjust new_sequence and do compare
00104         new_sequence |= ([udpStats sequence] & 0xFFFF0000);
00105         
00106         if (new_sequence > [udpStats sequence]) {
00107             // accept
00108             if (new_sequence != [udpStats sequence] + 1) {
00109                 int diff = (new_sequence - [udpStats sequence]) - 1;
00110                 [udpStats increaseUdpDroppedBy:diff];
00111                 [udpStats increaseUdpTotalBy:diff];             // want TOTAL packets
00112                 [udpStats increaseRecentDroppedBy:diff];
00113                 [udpStats increaseRecentCountBy:diff];
00114                 [notificationCenter postNotificationName:@"SRU_UDP_STATS_LOST_SOME" 
00115                                                   object:self userInfo:udpStats];
00116             }
00117             [udpStats setSequence: new_sequence];
00118             // S_P2
00119             if ([communication shortVersion] == COMM_SHORTVERSION && [communication receiveShort]) {
00120                 Player *me = [universe playerThatIsMe];
00121                 [me setFlags: ([me flags] & 0xFFFF00FF) | (buffer & 0xFF) << 8];
00122             }            
00123             else {
00124                 // reject
00125                 /*
00126                 if (buffer[0] == SP_SC_SEQUENCE) {
00127                     if(Communications.UDP_DIAG) 
00128                         System.out.println("(ignoring repeat " + new_sequence + ')');
00129                 }
00130                  else {
00131                      if(Communications.UDP_DIAG) 
00132                          System.out.println("sequence=" + sequence + ", new_sequence=" + new_sequence + ", ignoring transmission");
00133                  } */
00134                 // the remaining packets will be dropped and we shouldn't count the SP_SEQUENCE packet either
00135                 [communication decreasePacketsReceived];
00136                 NSLog(@"ServerReaderUdp.handleSequence: rejected out of sequence packet");
00137             }
00138         }
00139         if ([udpStats recentCount] > UDP_RECENT_INTR) {
00140             // once a minute (at 5 upd/sec), report on how many were dropped
00141             // during the last UDP_RECENT_INTR updates 
00142             [udpStats setUdpRecentDropped:[udpStats recentDropped]];
00143             [udpStats setRecentCount:0];
00144             [udpStats setRecentDropped:0];
00145             [notificationCenter postNotificationName:@"SRU_UDP_STATS_CHANGED" 
00146                                               object:self userInfo:udpStats];
00147         }
00148     }
00149 }
00150 
00151 
00152 @end

Generated on Fri Jul 28 19:15:15 2006 for MacTrek by  doxygen 1.4.7