iOS learns socket Programming--http1.0 server-side from scratch

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.