Building an
ftp client and server using sockets
For a 1.5 additional hr lecture (not an official part of this class) walking through a simple ftp example:
Implementation:
the socket data structure
| Socket Structure Fields |
| socket type |
| socket options (from socket()) |
| time to "linger" |
| socket state (ISCONNECTED, ISCONNECTING, ) |
| pointer to lower level protocol info |
| pointer to accept() socket |
| queue, number of partially formed connections |
| max number of queued connections |
| queue, number of pending incoming connections |
| event to sleep on if no incoming connections |
| error flags |
| signaling information |
| out-of-band pointer |
| send buffer | fields/characteristics |
| number of bytes in buffer | |
| high water mark | |
| low water mark | |
| pointer to chair of buffers (mbufs) | |
| ptr to proc doing send/receive | |
| flags | |
| receive buffer | same fields as send buffer |
Implementations: OS actions on rcvfrom()
Transport Layer Interface for Unix System V, Release 4 (svr4)
| TLI Function | closest BSD call | comments |
| t_open() | socket() | |
| t_bind() | bind(), listen() | does work of BSD bind and listen |
| t_listen() | accept() | waits for request but does not accept it. Returns info on client |
| t_snddis() | reject client without accept | |
| t_accept() | accept() | TLI will not create new endpoint. BSD accept()=t_list+t_open+t_accept |
| t_connect() | connect() | |
| t_send() | send() | |
| t_recv() | recv() | |
| t_sendudata() | sendto() | |
| t_recvudata() | rcvfrom() | |
| t_look() | get current event from transport connection | |
| t_getstate() | get current state of transport connection |
The Windows Sockets specification includes the following
Berkeley-style socket routines:
| accept() * | An incoming connection is acknowledged and associated with an immediately created socket. The original socket is returned to the listening state. |
| bind() | Assign a local name to an unnamed socket. |
| closesocket() * | Remove a socket from the per-process object reference table. Only blocks if SO_LINGER is set. |
| connect() * | Initiate a connection on the specified socket. |
| getpeername() | Retrieve the name of the peer connected to the specified socket. |
| getsockname() | Retrieve the current name for the specified socket |
| getsockopt() | Retrieve options associated with the specified socket. |
| htonl() | Convert a 32-bit quantity from host byte order to network byte order. |
| htons() | Convert a 16-bit quantity from host byte order to network byte order. |
| inet_addr() | Converts a character string representing a number in the Internet standard ".'' notation to an Internet address value. |
| inet_ntoa() | Converts an Internet address value to an ASCII string in ".'' notation i.e. "a.b.c.d''. |
| ioctlsocket() | Provide control for sockets. |
| listen() | Listen for incoming connections on a specified socket. |
| ntohl() | Convert a 32-bit quantity from network byte order to host byte order. |
| ntohs() | Convert a 16-bit quantity from network byte order to host byte order. |
| recv() * | Receive data from a connected socket. |
| recvfrom() * | Receive data from either a connected or unconnected socket. |
| select() * | Perform synchronous I/O multiplexing. |
| send() * | Send data to a connected socket. |
| sendto() * | Send data to either a connected or unconnected socket. |
| setsockopt() | Store options associated with the specified socket. |
| shutdown() | Shut down part of a full-duplex connection. |
| socket() | Create an endpoint for communication and return a socket. |
* = The routine can block if acting on a blocking socket.
| gethostbyaddr() * | Retrieve the name(s) and address corresponding to a network address. |
| gethostbyname() * | Retrieve the name(s) and address corresponding to a host name. |
| gethostname() | Retrieve the name of the local host. |
| getprotobyname() * | Retrieve the protocol name and number corresponding to a protocol name. |
| getprotobynumber() * | Retrieve the protocol name and number corresponding to a protocol number. |
| getservbyname() * | Retrieve the service name and port corresponding to a service name. |
| getservbyport() * | Retrieve the service name and port corresponding to a port. |
* = The routine can block under some circumstances.
| WSAAsyncGetHostByAddr() | A set of functions which provide asynchronous versions of the standard Berkeley getXbyY() functions. For example, the WSAAsyncGetHostByName() function provides an asynchronous message based implementation of the standard Berkeley gethostbyname() function. |
| WSAAsyncGetHostByName() | |
| WSAAsyncGetProtoByName() | |
| WSAAsyncGetProtoByNumber() | |
| WSAAsyncGetServByName() | |
| WSAAsyncGetServByPort() | |
| WSAAsyncSelect() | Perform asynchronous version of select() |
| WSACancelAsyncRequest() | Cancel an outstanding instance of a WSAAsyncGetXByY() function. |
| WSACancelBlockingCall() | Cancel an outstanding "blocking" API call |
| WSACleanup() | Sign off from the underlying Windows Sockets DLL. |
| WSAGetLastError() | Obtain details of last Windows Sockets API error |
| WSAIsBlocking() | Determine if the underlying Windows Sockets DLL is already blocking an existing call for this thread |
| WSASetBlockingHook() | "Hook" the blocking method used by the underlying Windows Sockets implementation |
| WSASetLastError() | Set the error to be returned by a subsequent WSAGetLastError() |
| WSAStartup() | Initialize the underlying Windows Sockets DLL. |
| WSAUnhookBlockingHook() | Restore the original blocking function |
// This example is from the book _Java in a Nutshell_
by David Flanagan.
// Written by David Flanagan. Copyright (c) 1996 O'Reilly &
Associates.
// You may study, use, modify, and distribute this example for
any purpose.
// This example is provided WITHOUT WARRANTY either expressed
or implied.
import java.io.*;
import java.net.*;
// This class sends the specified text as a datagram to port 6010
of the
// specified host.
public class UDPSend {
static final int port = 6010;
public static void main(String args[]) throws Exception {
if (args.length != 2) {
System.out.println("Usage: java UDPSend
System.exit(0);
}
// Get the internet address of the specified host
InetAddress address = InetAddress.getByName(args[0]);
// Convert the message to an array of bytes
int msglen = args[1].length();
byte[] message = new byte[msglen];
args[1].getBytes(0, msglen, message, 0);
// Initilize the packet with data and address
DatagramPacket packet = new DatagramPacket(message, msglen,
address, port);
// Create a socket, and send the packet through it.
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
}
}
// This example is from the book _Java in a Nutshell_ by David Flanagan.
// Written by David Flanagan. Copyright (c) 1996 O'Reilly & Associates.
// You may study, use, modify, and distribute this example for any purpose.
// This example is provided WITHOUT WARRANTY either expressed or implied.
import java.io.*;
import java.net.*;
// This program waits to receive datagrams sent to port 6010.
// When it receives one, it displays the sending host and port,
// and prints the contents of the datagram as a string.
public class UDPReceive {
static final int port = 6010;
public static void main(String args[]) throws Exception
{
byte[] buffer = new byte[1024];
String s;
// Create a packet with an empty buffer to receive data
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Create a socket to listen on the port.
DatagramSocket socket = new DatagramSocket(port);
for(;;) {
// Wait to receive a datagram
socket.receive(packet);
// Convert the contents to a string
s = new String(buffer, 0, 0, packet.getLength());
// And display them
System.out.println("UDPReceive: received from " +
packet.getAddress().getHostName() + ":" +
packet.getPort() + ": " + s);
}
}
}
Critical Assessment of Socket API:
"good" things about sockets/TLI/winsock/Java network API:
"bad" things about socket API:
Novell Networks: Netware API
Novell SAP protocol
Possible operations:
| service type | meaning |
| 1 | request for name/addr of all servers of specified type |
| 2 | response to type-1 request, periodic broadcast by server of its service, period broadcast by router of known services |
| 3 | same as type 1, but for nearest service |
| 4 | response to type-3 request |
OSI Application Service Entities
API: Summary