Large File Transfer using Objective-C ( XCode )
This video shows how to code an Objective-C application to transfer Large file in small chunks.
Mac OS X Version: 10.10.5
Xcode Version: 7.1.1
Enjoy!!!
don’t forget to subscribe on YouTube as more code coming.
Watch above video, configure your project and use below code
GUIHandler.h
// // GUIHandler.h // TCPDataTransfer // // Created by Rahul Yadav on 30/12/15. // Copyright © 2015 Rahul Yadav. All rights reserved. // #import <Foundation/Foundation.h> #import <Cocoa/Cocoa.h> #import "ServerThread.h" #import "ClientThread.h" @interface GUIHandler : NSObject{ ServerThread *obj_server_thread; ClientThread *obj_client_thread; @public __weak IBOutlet NSProgressIndicator *b_upload; } - (IBAction)StartServerNow:(id)sender; - (IBAction)StopServerNow:(id)sender; - (IBAction)ConnectToServerNow:(id)sender; - (IBAction)DisconnectFromServer:(id)sender; - (IBAction)SendDataToServer:(id)sender; @end
GUIHandler.m
// // GUIHandler.m // TCPDataTransfer // // Created by Rahul Yadav on 30/12/15. // Copyright © 2015 Rahul Yadav. All rights reserved. // #import "GUIHandler.h" @implementation GUIHandler - (IBAction)StartServerNow:(id)sender { obj_server_thread=[[ServerThread alloc]init]; [obj_server_thread initializeServer]; [obj_server_thread start]; } - (IBAction)StopServerNow:(id)sender { [obj_server_thread StopServer]; [obj_server_thread cancel]; } - (IBAction)ConnectToServerNow:(id)sender { obj_client_thread=[[ClientThread alloc]init]; [obj_client_thread InitializeClient]; obj_client_thread->tx_recv=b_upload; [obj_client_thread start]; } - (IBAction)DisconnectFromServer:(id)sender { [obj_client_thread DisconnectFromServer]; [obj_client_thread cancel]; } - (IBAction)SendDataToServer:(id)sender { //[obj_client_thread SendTCPDataPacket:[[tx_send_data stringValue]UTF8String]]; dispatch_async(dispatch_get_main_queue(), ^{ NSOpenPanel *opendlg=[NSOpenPanel openPanel]; [opendlg setCanChooseFiles:TRUE]; [opendlg beginWithCompletionHandler:^(NSInteger result) { if(result==NSFileHandlingPanelOKButton){ obj_client_thread->rf=[NSFileHandle fileHandleForReadingAtPath:[[opendlg URL] path]]; obj_client_thread->file_length=[obj_client_thread->rf seekToEndOfFile]; NSString *data=[[[opendlg URL] path] lastPathComponent]; [obj_client_thread SendTCPDataPacket:[@"123" UTF8String] data_to_send:[data UTF8String] data_length:[data length]]; } }]; }); } @end
ServerThread.h
// // ServerThread.h // TCPDataTransfer // // Created by Rahul Yadav on 30/12/15. // Copyright © 2015 Rahul Yadav. All rights reserved. // #import <Foundation/Foundation.h> #import <Cocoa/Cocoa.h> #include <sys/socket.h> #include <netinet/in.h> @interface ServerThread : NSThread { CFSocketRef obj_server; @public } -(void)initializeServer; -(void)main; -(void)StopServer; @end
ServerThread.m
// // ServerThread.m // TCPDataTransfer // // Created by Rahul Yadav on 30/12/15. // Copyright © 2015 Rahul Yadav. All rights reserved. // #import "ServerThread.h" #import "ClientThread.h" @implementation ServerThread -(void)initializeServer{ CFSocketContext sctx={0,(__bridge void *)(self),NULL,NULL,NULL}; obj_server=CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, TCPServerCallBackHandler, &sctx); int so_reuse_flag=1; setsockopt(CFSocketGetNative(obj_server), SOL_SOCKET, SO_REUSEADDR, &so_reuse_flag, sizeof(so_reuse_flag)); setsockopt(CFSocketGetNative(obj_server), SOL_SOCKET, SO_REUSEPORT, &so_reuse_flag, sizeof(so_reuse_flag)); struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_len=sizeof(sock_addr); sock_addr.sin_family=AF_INET; sock_addr.sin_port=htons(6658); sock_addr.sin_addr.s_addr=INADDR_ANY; CFDataRef dref=CFDataCreate(kCFAllocatorDefault, (UInt8*)&sock_addr, sizeof(sock_addr)); CFSocketSetAddress(obj_server, dref); CFRelease(dref); } -(void)main{ CFRunLoopSourceRef loopref=CFSocketCreateRunLoopSource(kCFAllocatorDefault, obj_server, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), loopref, kCFRunLoopDefaultMode); CFRelease(loopref); CFRunLoopRun(); } -(void)StopServer{ CFSocketInvalidate(obj_server); CFRelease(obj_server); CFRunLoopStop(CFRunLoopGetCurrent()); } void TCPServerCallBackHandler(CFSocketRef s, CFSocketCallBackType callbacktype,CFDataRef address, const void *data,void *info){ switch (callbacktype) { case kCFSocketAcceptCallBack: { ClientThread *obj_accepted_socket=[[ClientThread alloc]init]; [obj_accepted_socket InitializeNative:*(CFSocketNativeHandle*)data]; [obj_accepted_socket start]; } break; default: break; } } @end
ClientThread.h
// // ClientThread.h // TCPDataTransfer // // Created by Rahul Yadav on 30/12/15. // Copyright © 2015 Rahul Yadav. All rights reserved. // #import <Foundation/Foundation.h> #import <Cocoa/Cocoa.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> @interface ClientThread : NSThread{ CFSocketRef obj_client; @public NSProgressIndicator* tx_recv; NSFileHandle *rf; long file_pointer; long file_length; } -(void)InitializeClient; -(void)InitializeNative:(CFSocketNativeHandle) native_socket; -(void)main; -(void)DisconnectFromServer; -(void)SendTCPDataPacket:(const char *)cmd data_to_send:(const char*) data data_length:(long)target_data_length; -(char*)ReadData:(int*)recv_data_length; @end
ClientThread.m
// // ClientThread.m // TCPDataTransfer // // Created by Rahul Yadav on 30/12/15. // Copyright © 2015 Rahul Yadav. All rights reserved. // #import "ClientThread.h" @implementation ClientThread -(void)InitializeClient{ CFSocketContext sctx={0,(__bridge void *)(self),NULL,NULL,NULL}; obj_client=CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketConnectCallBack|kCFSocketReadCallBack, TCPClientCallBackHandler, &sctx); struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_len=sizeof(sock_addr); sock_addr.sin_family=AF_INET; sock_addr.sin_port=htons(6658); inet_pton(AF_INET, "127.0.0.1", &sock_addr.sin_addr); CFDataRef dref=CFDataCreate(kCFAllocatorDefault, (UInt8*)&sock_addr, sizeof(sock_addr)); CFSocketConnectToAddress(obj_client, dref, -1); CFRelease(dref); } -(void)main{ CFRunLoopSourceRef loopref=CFSocketCreateRunLoopSource(kCFAllocatorDefault, obj_client, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), loopref, kCFRunLoopDefaultMode); CFRelease(loopref); CFRunLoopRun(); } -(void)DisconnectFromServer{ CFSocketInvalidate(obj_client); CFRelease(obj_client); CFRunLoopStop(CFRunLoopGetCurrent()); } -(void)SendTCPDataPacket:(const char *)cmd data_to_send:(const char*) data data_length:(long)target_data_length { int initialize[1]={2};//initialize int separator[1]={4}; int target_length=snprintf(NULL, 0, "%ld",target_data_length); char* data_length_char=malloc(target_length+1); snprintf(data_length_char, target_length+1, "%ld",target_data_length);// this line of code convert (45 into "45") int ele_count=(int)strlen(data_length_char); long packet_length= 1+strlen(cmd)+ele_count+1+target_data_length; UInt8 *packet=(UInt8*)malloc(packet_length * sizeof(UInt8)); memcpy(&packet[0], initialize, 1); memcpy(&packet[0+1], cmd, strlen(cmd)); memcpy(&packet[0+1+strlen(cmd)],data_length_char , ele_count); memcpy(&packet[0+1+strlen(cmd)+ele_count], separator, 1); memcpy(&packet[0+1+strlen(cmd)+ele_count+1], data, target_data_length); CFDataRef dref=CFDataCreate(kCFAllocatorDefault, packet, packet_length); CFSocketSendData(obj_client, NULL, dref, -1); free(packet); free(data_length_char); CFRelease(dref); } -(void)InitializeNative:(CFSocketNativeHandle) native_socket{ CFSocketContext sctx={0,(__bridge void *)(self),NULL,NULL,NULL}; obj_client=CFSocketCreateWithNative(kCFAllocatorDefault, native_socket, kCFSocketReadCallBack, TCPClientCallBackHandler, &sctx); } -(char*)ReadData:(int*)recv_data_length{ char *data_buff; NSMutableString *buff_length=[[NSMutableString alloc]init]; char buf[1]; read(CFSocketGetNative(obj_client), &buf, 1 ); while ((int)*buf!=4) { [buff_length appendFormat:@"%c", (char)(int)*buf]; read(CFSocketGetNative(obj_client), &buf, 1 ); } int data_length=[[buff_length stringByTrimmingCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet]invertedSet]]intValue]; *recv_data_length=data_length; data_buff=(char*)malloc(data_length*sizeof(char)); ssize_t byte_read=0; ssize_t byte_offset=0; while (byte_offset<data_length) { byte_read=read(CFSocketGetNative(obj_client), data_buff+byte_offset, 50); byte_offset+=byte_read; } return data_buff; } void TCPClientCallBackHandler(CFSocketRef s, CFSocketCallBackType callbacktype,CFDataRef address, const void *data,void *info){ switch (callbacktype) { case kCFSocketConnectCallBack: if(data){ CFSocketInvalidate(s); CFRelease(s); CFRunLoopStop(CFRunLoopGetCurrent()); } else{ NSLog(@"Client Connected to Server"); } break; case kCFSocketReadCallBack:{ char buf[1]; read(CFSocketGetNative(s), &buf, 1 ); if((int)*buf==2){ ClientThread * obj_client_ptr=(__bridge ClientThread*) info; char cmd[3]; read(CFSocketGetNative(s), &cmd, 3 ); int iCmd; int irecv_data_length; sscanf(cmd, "%d",&iCmd); char *recv_data=[obj_client_ptr ReadData:&irecv_data_length]; //[obj_client_ptr->tx_recv setStringValue:[NSString stringWithUTF8String:recv_data]]; switch (iCmd) { case 123://server side { NSFileManager *fmng=[NSFileManager defaultManager]; [fmng createFileAtPath:[NSString stringWithFormat:@"/Users/rahulsnippet/Documents/%s",recv_data] contents:nil attributes:nil ]; obj_client_ptr->rf=[NSFileHandle fileHandleForWritingAtPath:[NSString stringWithFormat:@"/Users/rahulsnippet/Documents/%s",recv_data] ]; obj_client_ptr->file_pointer=0; int target_length=snprintf(NULL, 0, "%ld",obj_client_ptr->file_pointer); char* data_length_char=malloc(target_length+1); snprintf(data_length_char, target_length+1, "%ld",obj_client_ptr->file_pointer); [obj_client_ptr SendTCPDataPacket:[@"124" UTF8String] data_to_send:data_length_char data_length:strlen(data_length_char)]; } break; case 124://client side { sscanf(recv_data, "%ld",&obj_client_ptr->file_pointer); if(obj_client_ptr->file_pointer!=obj_client_ptr->file_length){ [obj_client_ptr->rf seekToFileOffset:obj_client_ptr->file_pointer]; long chunck_size=obj_client_ptr->file_length-obj_client_ptr->file_pointer<20000?obj_client_ptr->file_length-obj_client_ptr->file_pointer:20000; ; [obj_client_ptr SendTCPDataPacket:[@"125" UTF8String] data_to_send:[[obj_client_ptr->rf readDataOfLength:chunck_size] bytes] data_length:chunck_size]; [obj_client_ptr->tx_recv setDoubleValue:((double)obj_client_ptr->file_pointer+chunck_size/(double)obj_client_ptr->file_length)*100]; [obj_client_ptr->tx_recv setNeedsDisplay:YES]; } else{ [obj_client_ptr SendTCPDataPacket:[@"126" UTF8String] data_to_send:[@"Close" UTF8String] data_length:5]; [obj_client_ptr->rf closeFile]; obj_client_ptr->rf=nil; } }break; case 125: { [obj_client_ptr->rf seekToFileOffset:obj_client_ptr->file_pointer]; [obj_client_ptr->rf writeData:[NSData dataWithBytes:recv_data length:irecv_data_length]]; obj_client_ptr->file_pointer=[obj_client_ptr->rf offsetInFile]; int target_length=snprintf(NULL, 0, "%ld",obj_client_ptr->file_pointer); char* data_length_char=malloc(target_length+1); snprintf(data_length_char, target_length+1, "%ld",obj_client_ptr->file_pointer); [obj_client_ptr SendTCPDataPacket:[@"124" UTF8String] data_to_send:data_length_char data_length:strlen(data_length_char)]; free(data_length_char); } break; case 126: { [obj_client_ptr->rf closeFile]; obj_client_ptr->rf=nil; } break; default: break; } free(recv_data); } } break; default: break; } } @end