官术网_书友最值得收藏!

Creating a data client

In the Creating a data server recipe of this chapter, we updated our BSDSocketServer class so we could set up a server that could receive data. In this recipe, we will be updating our BSDSocketClient class so we can set up a client to upload data to our data server.

Getting ready

This recipe is compatible with both iOS and OS X. No extra frameworks or libraries are required.

How to do it…

Let's update the BSDSocketClient class to include our data client.

Updating the BSDSocketClient header file

Since we will be able to use the same constructor (initWithAddress:andPort:) that we used when we connected to the echo server, all we need to do is to add a method to send the data itself. This method will be called sendData:toSocket:. The following is the new BSDSocketClient header file:

  #import <Foundation/Foundation.h>
  
  typedef NS_ENUM(NSUInteger, BSDClientErrorCode) {
    NOERRROR,
    SOCKETERROR,
    CONNECTERROR,
    READERROR,
    WRITEERROR
};  
  #define MAXLINE 4096
  
  @interface BSDSocketClient : NSObject
  
  @property int errorCode, sockfd;
  
  -(id)initWithAddress:(NSString *)addr andPort:(int)port;
  -(ssize_t) writtenToSocket:(int)sockfdNum withChar:(NSString *)vptr;
  -(NSString *) recvFromSocket:(int)lsockfd withMaxChar:(int)max;
  -(ssize_t)sendData:(NSData *)data toSocket:(int)lsockfd;
  
  @end

Updating the BSDSocketClient implementation file

We now need to add the sendData:toSocket: method to our BSDSocketClient class:

-(ssize_t)sendData:(NSData *)data toSocket:(int)lsockfd
 {
     NSLog(@"sending");
     ssize_t n;
     const UInt8 *buf = (const UInt8 *)[data bytes];
 
     if ((n = send(lsockfd, buf,[data length],0)) <=0) {
         errorCode = WRITEERROR;
         return -1;
     } else {
         errorCode = NOERRROR;
         return n;
     }
 }

The sendData:toSocket: method accepts two parameters: the data to send to the server and the socket descriptor to which we want to send the data. Since the BSD Socket Library does not recognize the NSData objects, we will need to convert the data to bytes and then to a UInt8 buffer prior to sending it.

Once we have our UInt8 buffer, we use the send() function to send the data to the server. The send() function will return the number of bytes sent to the server; if that number is less than 0, it means there is a problem and we return an error.

Using the BSDSocketClient to connect to our data server

Let's take a look at the sample code that uses the sendData:toSocket method:

  BSDSocketClient *bsdCli = [[BSDSocketClient alloc] initWithAddress:@"127.0.0.1" andPort:2006];
  if (bsdCli.errorCode == NOERRROR) {
      NSData *data = [NSData dataWithContentsOfFile:@"/Users/hoffmanjon/Documents/GreenGuyLarge.png"];
      [bsdCli sendData:data toSocket:bsdCli.sockfd];
  } else {
      NSLog(@"%@",[NSString stringWithFormat:@"Error code %d recieved. ", bsdCli.errorCode]);
  }

We start off by initializing the BSDSocketClient object with the IP address 127.0.0.1 and with a port of 2006. If you are running the sample server on another device, you will need to change the IP address. If there are no issues initializing the client, we load an image and convert it to an NSData object. You will need to change the location of the file to the location on your machine that contains an image.

We then pass the NSData object that contains the image to the sendData:toSocket method.

How it works…

When we created the BSD data server, we went through a three-step process to prepare the TCP server and to create listen on the socket. These were socket (create a socket), bind (bind the socket to the interface), and listen (listen for incoming connections).

When we create the BSD data client, we make the connection in a two-step process. These steps are socket (create a socket just like the echo server) and connect (this connects to the server). The client calls the connect() function to establish a connection with the server. If no error occurs, we have a connection between the server and the client. This connection process is the same code we used to establish a connection with the echo server.

Once we have the connection established with the server, we need to send our data to the server. In our example, we will be sending an image file over; however, this same code can be used to send any binary file. The client and the server just need to agree on what type of file is to be sent.

The first thing we need to do is to convert the file to an NSData object and pass that to the sendData:toScoket: method. When the sendData:toSocket: method has the NSData object, it converts it to a Uint8 buffer. We then use the send() function to send the Uint8 buffer to the server.

主站蜘蛛池模板: 鹤岗市| 潮安县| 广宗县| 胶南市| 浑源县| 延安市| 阳东县| 青浦区| 镇赉县| 马边| 洛南县| 福泉市| 黑龙江省| 和静县| 禹城市| 绿春县| 仙桃市| 黄陵县| 武清区| 大冶市| 岳池县| 和平区| 青冈县| 渝北区| 彰化县| 横峰县| 陇川县| 偏关县| 太康县| 姚安县| 团风县| 嘉鱼县| 潢川县| 松溪县| 太和县| 宿松县| 咸丰县| 淄博市| 徐汇区| 集贤县| 贡山|