The client uses the iPhone application, and the screen is relatively simple. Click the send button to send some strings to the server. Click the receive button to read some strings from the server and display them on the screen.
The UI section of the client application is not introduced anymore. Let's look at the code section directly. The Socket Client can adopt cfstream or nsstream. The cfstream implementation method is basically the same as that of the server. To introduce more knowledge to readers, we use nsstream in this example. Nsstream adopts objective-C language and some object-oriented classes.
Next let's take a look at the client View Controller viewcontroller. h
# Import <corefoundation/corefoundation. h> # include <sys/socket. h> # include <netinet/in. h> # Define port 9000 @ interface viewcontroller: uiviewcontroller <nsstreamdelegate> {int flag; // The operation flag 0 indicates sending 1 as receiving} @ property (nonatomic, retain) nsinputstream * inputstream; @ property (nonatomic, retain) nsoutputstream * outputstream; @ property (weak, nonatomic) iboutlet uilabel * message;-(ibaction) senddata :( ID) sender;-(ibaction) receivedata :( ID) sender; @ end
Define the attributes inputstream and outputstream. They input the nsinputstream stream and the nsoutputstream class of the output stream. They correspond to the input stream cfreadstreamref in the cfstream Implementation of the server and the output stream cfwritestreamref.
The initialization network method initnetworkcommunication code of viewcontroller. m is as follows:
- (void)initNetworkCommunication{CFReadStreamRef readStream;CFWriteStreamRef writeStream;CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)@”192.168.1.103″, PORT, &readStream, &writeStream); ①_inputStream = (__bridge_transfer NSInputStream *)readStream; ②_outputStream = (__bridge_transfer NSOutputStream*)writeStream; ③[_inputStream setDelegate:self]; ④[_outputStream setDelegate:self]; ⑤[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode]; ⑥[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode]; ⑦[_inputStream open]; ⑧[_outputStream open]; ⑨}
The method for triggering by clicking the send and receive buttons is as follows:
/* Click the send button */-(ibaction) senddata :( ID) sender {flag = 0; [self initnetworkcommunication];}/* click the receive button */-(ibaction) receivedata :( ID) sender {flag = 1; [self initnetworkcommunication];}
Both call the initnetworkcommunication method and set the operation identifier flag. If the flag is 0, the flag is 1 to receive data.
Changing the stream status triggers many events and calls back the stream: handleevent: method defined in nsstreamdelegate. The Code is as follows:
-(Void) stream :( nsstream *) thestream handleevent :( nsstreamevent) streamevent {nsstring * event; Switch (streamevent) {Case nsstreameventnone: event = @ "nsstreameventnone"; break; Case nsstreameventopencompleted: event = @ "nsstreameventopencompleted"; break; Case nsstreameventhasbytesavailable: event = @ "nsstreameventhasbytesavailable"; if (flag = 1 & thestream = _ inputstream) {nsmutabledata * input = [nsmuta Bledata alloc] init]; uint8_t buffer [1024]; ① int Len; while ([_ inputstream hasbytesavailable]) ② {Len = [_ inputstream read: Buffer maxlength: sizeof (buffer)]; ③ if (LEN> 0) {[input appendbytes: Buffer length: Len] ;}} nsstring * resultstring = [[nsstring alloc] initwithdata: Input encoding: nsutf8stringencoding]; nslog (@ "receive: % @", resultstring); _ message. TEXT = resultstring;} break; Case nsstreameventhasspaceavailable: Event = @ "nsstreameventhasspaceavailable"; if (flag = 0 & thestream = _ outputstream) {// output uint8 buff [] = "Hello server !"; ④ [_ Outputstream write: buff maxlength: strlen (const char *) buff) + 1]; ⑤ // close the output stream [_ outputstream close];} break; Case nsstreameventerroroccurred: event = @ "nsstreameventerroroccurred"; [self close]; ⑥ break; Case nsstreameventendencountered: event = @ "nsstreameventendencountered"; nslog (@ "error: % d: % @", [[thestream streamerror] Code], [[thestream streamerror] localizeddescription]); break; default: [self close]; 7event = @ "unknown"; break ;} nslog (@ "event -- % @", event );}
In the nsstreameventhasbytesavailable, code ① reads the data preparation buffer. In this example, it is set to 1024 bytes, which affects the stream reading. The Code in line ② uses the hasbytesavailable method to determine whether the stream has data that can be read. If there is readable data, it reads it cyclically. The Code in line ③ reads data to the buffer using the stream read: maxlength: method. The first parameter is the buffer object buffer, and the second parameter is the byte length of the read buffer.
In the nsstreameventhasspaceavailable, line ④ of the Code is the data to be written. Line ⑤ code [_ outputstream write: buff maxlength: strlen (const char *) buff) + 1] is written as a data method.
Lines 6 and 7 [self close] Call the close method to close the code. The close method code is as follows:
-(void)close{[_outputStream close];[_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];[_outputStream setDelegate:nil];[_inputStream close];[_inputStream removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];[_inputStream setDelegate:nil];}