Upload a file to a server

This app is a client that uploads one image file to a server running on i5.nyu.edu. The server places the image in the images subdirectory of the server’s current directory, which is /home1/m/mm64/INFO1-CE9236/src/put. You can see this images subdirectory by pointing your browser at http://i5.nyu.edu/~mm64/INFO1-CE9236/src/put/images/.

I followed the example Simple URL Connections. Also see Estimating upload progress.

Source code in Put.zip

This source code is only the client. You also need the server server.py. The client and server have to agree on the TCP/IP port number (3000).

To keep things simple, I put everything into class View. In real life, the networking code would be in the application delegate or in the view controller.

  1. main.m
  2. Class PutAppDelegate
  3. Class View

Create the project

Move or copy the image file spj224.png into the root folder of the project, and add it to the project.

The TCP/IP port number

A TCP/IP server running on i5.nyu.edu must be bound to a port in the range 3000 to 3199 inclusive, a policy set by our superuser. The TCP/IP port numbers currently in use are the numbers after the last (or only) dot in column 1:

netstat -an -f inet -P tcp

TCP: IPv4
   Local Address        Remote Address    Swind Send-Q Rwind Recv-Q    State
-------------------- -------------------- ----- ------ ----- ------ -----------
128.122.109.53.22    69.204.232.159.51486 524280      0 66608      0 ESTABLISHED
128.122.109.53.80    172.26.25.119.59544  524280      0 65664      0 FIN_WAIT_2
128.122.109.53.80    172.26.25.119.59546  524280      0 65664      0 FIN_WAIT_2
128.122.109.53.80    172.26.25.119.59547  524200      0 65664      0 FIN_WAIT_2
      *.111                *.*                0      0 65536      0 LISTEN
      *.*                  *.*                0      0 65536      0 IDLE
      *.22                 *.*                0      0 65536      0 LISTEN
      *.7100               *.*                0      0 65536      0 LISTEN
      *.6481               *.*                0      0 65536      0 LISTEN
      *.80                 *.*                0      0 65536      0 LISTEN
      *.3306               *.*                0      0 65536      0 LISTEN
128.122.109.53.22    192.168.66.90.49281  524280      0 66608      0 ESTABLISHED
128.122.109.53.22    192.168.66.90.49285  524280      0 66608      0 ESTABLISHED
      *.25                 *.*                0      0 65536      0 LISTEN

The following shellscript is written in the language of the Korn Shell (ksh). It runs on i5.nyu.edu.

#!/bin/ksh
#Output the TCP/IP port numbners currently in use.

netstat -an -f inet -P tcp |
awk 'NR > 4 {print $1}' |	#Output the first field.
awk -F. '{print $NF}' |		#Output the last field of the first field.
grep '^[0-9][0-9]*$' |		#Discard any lines that are not all digits.
sort -nu			#Increasing numerical order, discard duplicates.

exit 0
22
25
80
111
3306
6481
7100

You can also run netstat with the same command line arguments in the Terminal window on a Mac. Here’s its Mac manual page.

Launch the server

The server server.py is written in the language Python and runs on i5.nyu.edu. The server must be launched before the client tries to upload the image. Launch it “in the background” with an ampersand to let the shell prompt reappear immediately, and with nohup so that the server keeps running even after we log out from i5.nyu.edu.

cd /home1/m/mm64/public_html/INFO1-CE9236/src/put
pwd
nohup server.py &
netstat -an -f inet -P tcp

The server produces the following output:

gImageDirPath == "./images"
Server is running on i5.nyu.edu.
Server has accepted a client.
fileLength == 221607
filePath == "./images/spj224.png"
ND-IMAC-13.NDLAB.ITS.NYU.EDU - - [17/Nov/2010 12:15:33] "PUT /spj224.png HTTP/1.1" 201 -

The server refuses to overwrite an existing file with the same name as the file being uploaded. It gives the message

ND-IMAC-13.NDLAB.ITS.NYU.EDU - - [17/Nov/2010 12:22:52] code 500, message Internal Server Error

What the server on i5.nyu.edu receives from the client on the iPhone

Each line ends with the two characters \r\n. The last line consists of only the two characters \r\n. After that comes the bytes of the png file.

PUT /spj224.png HTTP/1.1
Host: i5.nyu.edu:3000
User-Agent: Put/1.0 CFNetwork/485.2 Darwin/10.4.0
Content-Type: image/png
Content-Length: 221607
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive

Things to try

  1. Get the picture from the iPhone camera.