In the previous article, "iOS from the zero-learning socket programming--http1.0 Client" has simply introduced socket programming and some basic principles. and implemented a simple iOS client (original address: http://blog.csdn.net/abc649395594/article/details/45081567)
Here is a brief introduction to how to use OC to build the server side of the socket. Although this is not a good solution, we usually use Java or PHP or Nodejs to build the server backend. However, it is necessary to understand the OC approach, the way to deepen the understanding of socket programming.
Needless to say, import AsyncSocket.h and asyncsocket.m files. Here we create a desktop-side software (iOS side is also available.) ), a AppController class was created.
Below the code directly, a little longer, will slowly explain. The original program has a graphical interface, but in order to better explain how the socket works, here will be unnecessary
//appcontroller.h#import <Cocoa/Cocoa.h> #import "AsyncSocket.h" @interface appcontroller : nsobject<asyncsocketdelegate>{Asyncsocket *listensocket;Nsmutablearray*connectedsockets;BOOLisrunning;Iboutlet IDLogView;Iboutlet IDPortfield;Iboutlet IDStartstopbutton;}@property(Atomic,Strong)NSString*filename;@property(Atomic,Strong) Nsmutabledata *receivedata;-(ibaction) Startstop: (ID) sender;@end
The AppController.h file is very simple, there is a socket object for the Asyncsocket class, and an array to hold the connected socket. IsRunning Indicates whether it is running, and three iboutlet are required by the interface. FileName is used to read the file name of the HTTP request, and there is an action event that fires when the start/END key is pressed.
#import "AppController.h" #import "AsyncSocket.h" #import <AppKit/AppKit.h> #define WELCOME_MSG 0#define ECHO_MSG 1#define WARNING_MSG 2#define READ_TIMEOUT 15.0#define READ_TIMEOUT_EXTENSION 10.0#define FORMAT (format, ...) [NSString stringWithFormat: (format), # #__VA_ARGS__] @interface appcontroller (privateapi)@end @implementation appcontroller @synthesizefilename;-(ID) init{if(( Self= [SuperInit]) {listensocket = [[Asyncsocket alloc] Initwithdelegate: Self]; Connectedsockets = [[NsmutablearrayAlloc] Initwithcapacity:1]; IsRunning =NO; }return Self;} - (void) awakefromnib{[LogView setstring:@""];} - (void) Applicationdidfinishlaunching: (nsnotification*) anotification{[Listensocket setrunloopmodes:[NsarrayArraywithobject:nsrunloopcommonmodes]];} - (ibaction) Startstop: (ID) sender{if(!isrunning) {intPort = [Portfield intvalue];if(Port <0|| Port >65535) {port =0; }Nserror*error =Nil;if(! [Listensocket acceptonport:port Error:&error]) {return; } isrunning =YES; [Portfield setenabled:NO]; [Startstopbutton settitle:@"Stop"]; }Else{//Stop Accepting connections[Listensocket disconnect];//Stop any client connectionsNsuinteger i; for(i =0; i < [connectedsockets count]; i++) {[[Connectedsockets objectatindex:i] disconnect]; } isrunning =false; [Portfield setenabled:YES]; [Startstopbutton settitle:@"Start"]; }}- (void) Onsocket: (Asyncsocket *) sock didacceptnewsocket: (Asyncsocket *) newsocket{[connectedsockets addobject:newsocket];} - (void) Onsocket: (Asyncsocket *) sock didconnecttohost: (NSString*) host Port: (UInt16) port{[sock readdatawithtimeout:-1Tag0];//very Important NSString*welcomemsg = @"Welcome to the Asyncsocket Echo server\r\n"; NSData *welcomedata = [welcomemsg datausingencoding:nsutf8stringencoding]; [Sock readdatatodata:[asyncsocket Crlfdata] withtimeout:read_timeout tag:0];} - (void) Onsocket: (Asyncsocket *) sock Didwritedatawithtag: (Long) tag{if(tag = = echo_msg) {[sock readdatatodata:[asyncsocket crlfdata] withtimeout:read_timeout tag:0]; }}- (void) Onsocket: (Asyncsocket *) sock didreaddata: (NSData *) data withtag: (Long) tag{NSString*msg = [[NSStringAlloc] Initwithdata:strdata encoding:nsutf8stringencoding];NsrangeEndRange = [MSG rangeofstring:@"HTTP"];NsrangeBeginrange = [MSG rangeofstring:@"/"];if(Beginrange. location!=Nsnotfound&& EndRange. location!=Nsnotfound) {NsrangeFilerange = Nsmakerange (beginrange. location, EndRange. location-Beginrange. location-1); FileName = [msg substringwithrange:filerange];if(FileName &&!) [FileName isequaltostring:@""]) {NSData *returndata = [ SelfGetresponseheader:filename]; [Sock Writedata:returndata withtimeout:-1TAG:ECHO_MSG]; FileName =Nil; [Sock disconnectafterwriting]; }Else{[Sock Writedata:data withtimeout:-1TAG:ECHO_MSG]; FileName =Nil; [Sock disconnectafterwriting]; } }Else{NSLog(@"Header not Found");Dispatch_async(Dispatch_get_main_queue (), ^{[sock writedata:data withtimeout:-1TAG:ECHO_MSG]; FileName =Nil; [Sock disconnectafterwriting]; }); }}/** * This method is called if a read have timed out. * It allows us-optionally extend the timeout. * We Use this Me Thod to issue a warning to the user prior to disconnecting them.**/- (Nstimeinterval) Onsocket: (Asyncsocket *) sock Shouldtimeoutreadwithtag: (Long) Tag Elapsed: (Nstimeinterval) Elapsed Bytesdone: (Nsuinteger) length{if(Elapsed <= Read_timeout) {NSString*warningmsg = @"is you still there?\r\n"; NSData *warningdata = [warningmsg datausingencoding:nsutf8stringencoding]; [Sock Writedata:warningdata withtimeout:-1TAG:WARNING_MSG];returnRead_timeout_extension; }return 0.0;} - (void) Onsocket: (Asyncsocket *) sock willdisconnectwitherror: (Nserror*) err{[ SelfLoginfo:format (@"Client disconnected:%@:%hu", [sock Connectedhost], [sock connectedport]);} - (void) Onsocketdiddisconnect: (Asyncsocket *) sock{[connectedsockets Removeobject:sock];} -(NSData *) getResponseHeader: (NSString*) localfilename{//Get response Header nsmutablestring*header = [[nsmutablestringAlloc]init]; Nsmutabledata *returndata = [[Nsmutabledata alloc]init]; NSData *filecontent = [NSData datawithcontentsoffile:localfilename];intContentLength = (int) [filecontent length]; [Header appendstring:@"http/1.0 ok\r\n"]; [Header appendstring:@"connection:close\r\n"]; [Header appendstring:@"server:apache/1.3.0 (Unix) \ r \ n"];NSString*contentlengthstring = [NSStringstringwithformat:@"content-length:%d\r\n", ContentLength]; [Header appendstring:contentlengthstring];NSString*mimestring = [NSStringstringwithformat:@"Content-type:%@\r\n",[ SelfGetmimebyfilename:localfilename]]; [Header appendstring:mimestring]; [Header appendstring:@"\ r \ n"]; NSData *headerdata = [Header datausingencoding:nsutf8stringencoding];NSLog(@"header =%@", header); [Returndata Appenddata:headerdata]; [Returndata appenddata:filecontent];//nslog (@ "Return data =%@", returndata); return(NSData *) returndata;} - (NSString*) Getmimebyfilename: (NSString*) localfilename{//Determine the MIME type of the response header by file name NsrangeHtmlrange = [LocalFilename rangeofstring:@"HTML"];NsrangeHtmrange = [LocalFilename rangeofstring:@"htm"];NsrangePngrange = [LocalFilename rangeofstring:@"PNG"];if(Htmlrange. location!=Nsnotfound|| Htmrange. location!=Nsnotfound) {NSString*mime = [[NSStringalloc]initwithformat:@"Text/html"];returnMime }Else if(Pngrange. location!=Nsnotfound){NSString*mime = [[NSStringalloc]initwithformat:@"Image/png"];returnMime }NSString*mime = [[NSStringalloc]initwithformat:@"Unknown"];returnMIME;}@end
Because the storyboard file cannot be uploaded, the above code only shows the workflow of the socket server and cannot be copied directly. You need to write your own graphical interface or binding port number.
For a detailed analysis of the problems and workarounds encountered in the use of the Didreaddata method, see another article-"Asyncsocket didreaddata function"
Address: http://blog.csdn.net/abc649395594/article/details/45046871
iOS learns socket Programming--http1.0 server-side from scratch