Instructional Objectives
After participating in this practicum, students are expected to be able to:
- Understanding port usage.
- Understand the use of sockets for servers and clients.
1. Port
The numbers below 1024 are commonly used ports and are assigned by the IANA (Internet Assigned Number Authority). Table 5.1 below lists some commonly used TCP ports.
Table 5.1. Example of Well Known Port
2. Socket For Client
The java.net.Socket class is a fundamental Java class for performing client-side TCP operations.
import java.net.*;
import java.io.*
public class myport {
public static void main(String[] args) {
Socket theSocket
String host = "localhost"
for (int i = 0; i <=100; i++) {
try {
heSocket = new Socket(host, i);
System.out.println("There is a server on port " + i + " of " + host);
} catch (UnknownHostException e) {
System.err.println(e); break;
} catch (IOException e) {
}
}
}
}
3. Socket for Server
The ServerSocket class contains everything needed to write a server in Java. It has a constructor that creates a new ServerSocket object, methods that listen for connections on a specified port, methods that configure server options for various sockets, and various common methods such as toString().
In Java programming the basic life cycle of a server program is:
- A new ServerSocket is created on a specified port using the ServerSocket() constructor.
- The ServerSocket listens for incoming connection attempts on a port using the accept() method.
- Depending on the server type, either Socket's getInputStream(), getOutputStream(), or both are called to obtain the input and output streams communicating with the client.
- The server and client interact according to an agreed protocol until it is time to close the connection.
- The server, client, or both closed the connection.
- The server returns to step 2 and waits for the next connection.
import java.net.*;
import java.io.*;
public class serverport {
public static void main(String[] args) {
ServerSocket theServer;
for (int i = 1024; i <= 65535; i++) {
try
theServer = new ServerSocket(i);
theServer.close();
} catch (IOException e) {
System.out.println("There is a server on port " + i + ".");
}
}
}
}
Socket Programming Scenarios
Socket programming uses a client-server system, where the client process talks to the server process and vice versa. For example, a client with a telnet application will contact a server running the telnetd application.
Figure 8.1 Client-Server
The flow diagram used is shown in;
Figure 8.2 Connection-oriented Program Flowchart
Figure 8.3 Connectionless-oriented Program Flowchart
1. Example of STREAM Based Server
/*
** server.c - a stream socket server demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
void sigchld_handler(int s)
{ while(wait(NULL) > 0);
}
int main(void)
{ int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information int sin_size; struct sigaction sa; int yes=1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1);
}
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { perror("setsockopt"); exit(1);
}
my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1)
{ perror("bind"); exit(1);
}
if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1);
} while(1) { // main accept() loop sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,
&sin_size)) == -1) { perror("accept"); continue;
}
printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr)); if (!fork()) { // this is the child process close(sockfd); // child doesn't need the listener if (send(new_fd, "Hello, world!\n", 14, 0) == -1) perror("send");
close(new_fd); exit(0);
}
close(new_fd); // parent doesn't need this
} return 0;
}
To try the server program run:
# telnet server 3490
2. STREAM Based Client Example
/*
** client.c - a stream socket client demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define PORT 3490 // the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once
int main(int argc, char *argv[])
{ int sockfd, numbytes; char buf[MAXDATASIZE]; struct hostent *he;
struct sockaddr_in their_addr; // connector's address information
if (argc != 2) { fprintf(stderr,"usage: client hostname\n"); exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1);
}
their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(PORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr))
== -1) { perror("connect"); exit(1);
}
if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1);
}
buf[numbytes] = '\0'; printf("Received: %s",buf);
close(sockfd); return 0;
}
This program searches for a server with port 3490 and receives a string from the server and displays it to the screen.
3. Socket with DATAGRAM
The listener program will be ready on a machine and will wait for packets to be sent to port 4950. The talker program will send packets to that port.
Listernet program listing:
~/*
** listener.c - a datagram sockets "server" demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MYPORT 4950 // the port users will be connecting to
#define MAXBUFLEN 100
int main(void)
{ int sockfd;
struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information int addr_len, numbytes; char buf[MAXBUFLEN];
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1);
}
my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == -1) {
perror("bind"); exit(1);
}
addr_len = sizeof(struct sockaddr);
if ((numbytes=recvfrom(sockfd,buf, MAXBUFLEN-1, 0,(struct sockaddr
*)&their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1);
}
printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr)); printf("packet is %d bytes long\n",numbytes);
buf[numbytes] = '\0';
printf("packet contains \"%s\"\n",buf); close(sockfd);
return 0;
}
Listing of talker programs:
/*
** talker.c - a datagram "client" demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MYPORT 4950 // the port users will be connecting to
int main(int argc, char *argv[])
{ int sockfd;
struct sockaddr_in their_addr; // connector's address information struct hostent *he;
int numbytes;
if (argc != 3) { fprintf(stderr,"usage: talker hostname message\n"); exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1);
}
their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(MYPORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,(struct sockaddr
*)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1);
}
printf("sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));
close(sockfd); return 0;
}
4. Advanced socket
This section explains the use of several functions that can support the work of network programs using socket programming.
4.1 Blocking
A server application can receive data packets simultaneously, for that it is necessary to release a limiter or what is called non-blocking. So that the server can receive data simultaneously.
In socket() initialization, socket initially has an initial blocking value. To make it non-blocking, call the fcntl() function. This can be seen in the following example:
#include <unistd.h>
#include <fcntl.h>
.
.
sockfd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
.
.
4.2. select() -- Synchronous I/O Multiplexing
With the select function, applications will be able to sort and process data at the same time. Example of using select().
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
To clarify, here is an example of a program that will wait for 2.5 seconds to see if any data comes in from keyboard input.
/*
** select.c - a select() demo
*/
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define STDIN 0 // file descriptor for standard input
int main(void)
{ struct timeval tv; fd_set readfds;
tv.tv_sec = 2; tv.tv_usec = 500000;
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
// don't care about writefds and exceptfds:
select(STDIN+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds)) printf("A key was pressed!\n");
else printf("Timed out.\n");
return 0;
}
Example of using select() in a multiperson chat server application.
/*
** selectserver.c - a cheezy multiperson chat server */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 9034 // port we're listening on
int main(void)
{
fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() struct sockaddr_in myaddr; // server address struct sockaddr_in remoteaddr; // client address int fdmax; // maximum file descriptor number int listener; // listening socket descriptor int newfd; // newly accept()ed socket descriptor char buf[256]; // buffer for client data int nbytes;
int yes=1; // for setsockopt() SO_REUSEADDR, below int addrlen; int i, j;
FD_ZERO(&master); // clear the master and temp sets
FD_ZERO(&read_fds);
// get the listener
if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1);
}
// lose the pesky "address already in use" error message
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1);
}
// bind
myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = INADDR_ANY; myaddr.sin_port = htons(PORT); memset(&(myaddr.sin_zero), '\0', 8);
if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) { perror("bind"); exit(1);
}
// listen
if (listen(listener, 10) == -1) { perror("listen"); exit(1);
}
// add the listener to the master set
FD_SET(listener, &master);
// keep track of the biggest file descriptor fdmax = listener; // so far, it's this one
// main loop for(;;) {
read_fds = master; // copy it
if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(1);
}
// run through the existing connections looking for data to read for(i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // we got one!! if (i == listener) { // handle new connections addrlen = sizeof(remoteaddr);
if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen))
== -1) {
perror("accept");
} else {
FD_SET(newfd, &master); // add to master set if (newfd > fdmax) { // keep track of the maximum fdmax = newfd;
}
printf("selectserver: new connection from %s on socket %d\n", inet_ntoa(remoteaddr.sin_addr), newfd);
}
} else {
// handle data from a client
if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { // got error or connection closed by client if (nbytes == 0) { // connection closed
printf("selectserver: socket %d hung up\n", i);
} else { perror("recv");
} close(i); // bye!
FD_CLR(i, &master); // remove from master set
} else {
// we got some data from a client for(j = 0; j <= fdmax; j++) {
// send to everyone!
if (FD_ISSET(j, &master)) {
// except the listener and ourselves if (j != listener && j != i) { if (send(j, buf, nbytes, 0) == -1) { perror("send");
}
}
}
}
}
} // it's SO UGLY!
}
}
} return 0;
}
What is a System Call?
System calls are functions in programming. These functions are used to run and access the network.
1. socket()
Use :
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
This function is used for initialization in socket usage. Where the domain contains AF_INET, while the type contains SOCK_STREAM or SOCK_DGRAM and the protocol contains the number 0.
SOCK_STREAM is used when using the TCP protocol and SOCK_DGRAM is used for the UDP protocol.
In addition to the above contents, there are many others and can be seen on the manual page.
2. bind()
Use :
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
The bind function is used to associate IP addresses and ports. The sockfd variable is obtained from the socket() function.
Example:
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MYPORT 3490
main()
{ int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); // do some error checking!
my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
// don't forget your error checking for bind(): bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)); .
.
.
If you want to use our machine's IP address, you can use:
my_addr.sin_port = 0; // choose an unused port at random my_addr.sin_addr.s_addr = INADDR_ANY; // use my IP address
3. connect()
Use :
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
The connect function is used to access a remote host.
Example :
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define DEST_IP "10.12.110.57"
#define DEST_PORT 23
main()
{ int sockfd;
struct sockaddr_in dest_addr; // will hold the destination addr
sockfd = socket(AF_INET, SOCK_STREAM, 0); // do some error checking!
dest_addr.sin_family = AF_INET; // host byte order
dest_addr.sin_port = htons(DEST_PORT); // short, network byte order dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
memset(&(dest_addr.sin_zero), '\0', 8); // zero the rest of the struct
// don't forget to error check the connect()! connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)); .
.
.
4. listen()
Use :
int listen(int sockfd, int backlog);
The function of the listen command is used to wait for a connection from a host.
5. accept()
Use :
#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);
The function of accept is used after the listen function. Where the socket will forward to the new socket variable after a host contacts. Accept will form a new socket and can be processed for send or recv.
Example :
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
main()
{ int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information int sin_size;
sockfd = socket(AF_INET, SOCK_STREAM, 0); // do some error checking!
my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
// don't forget your error checking for these calls:
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
listen(sockfd, BACKLOG);
sin_size = sizeof(struct sockaddr_in);
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); .
.
.
6. send() and recv()
Use :
int send(int sockfd, const void *msg, int len, int flags);
int recv(int sockfd, void *buf, int len, unsigned int flags);
The function of send and recv is for data exchange. The send() and recv() functions are used for data with connection-oriented protocols, while for connectionless-oriented protocols use sendto() and recvfrom().
The *msg pointer is the content of the data to be sent, as well as *buf is a pointer that contains the data received. The len variable is used as the length of the data.
Example :
char *msg = "Beej was here!"; int len, bytes_sent; . . len = strlen(msg);
bytes_sent = send(sockfd, msg, len, 0); .
.
.
7. sendto() and recvfrom()
Use :
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);
The function of sendto and recvfrom is to exchange data with the DGRAM protocol. The function is almost the same as the send and recv functions where there are additional variables, namely struct sockaddr *to, and int toleni.
8. close() and shutdown()
Use :
close(sockfd);
int shutdown(int sockfd, int how);
The close() and shutdown() functions are used to close a connection after exchanging data. Shutdown is used when a certain condition is desired, the variable is added to the how variable. The variable has a certain value and meaning, namely:
- 0 -- After closing, only receiving is allowed
- 1 -- After closing, only sending is allowed
- 2 -- After closing, receiving and sending are not allowed, same as close().
9. getpeername()
Use :
#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);
The getpeername() function is used to find out information about the destination.
10. gethostname()
Use :
#include <unistd.h>
int gethostname(char *hostname, size_t size);
The gethostname() function is used to find out information about our network machines.
11. DNS -- Sending to "whitehouse.gov", Answered "198.137.240.92"
Use :
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
The hostent structure has objects in it, including:
struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list;
};
#define h_addr h_addr_list[0]
Where :
- h_name -- the official name of a host
- h_aliases -- NULL , alternative names of a host
- h_addrtype -- type of address, example AF_INET
- h_length -- length of IP address data
- h_addr_list -- ZERO, set of IPs with that name
- h_addr -- first address of h_addr_list.
To get the results from the hostent structure, the gethostbyname() function is used. How to use it can be seen in the example program.
Example program:
/*
** getip.c - a hostname lookup demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{ struct hostent *h;
if (argc != 2) { // error check the command line fprintf(stderr,"usage: getip address\n"); exit(1);
}
if ((h=gethostbyname(argv[1])) == NULL) { // get the host info herror("gethostbyname"); exit(1);
}
printf("Host name : %s\n", h->h_name);
printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr))); return 0;
}
Programming with Socket API
Application Programming Interface (API) can be used by users to create an application. While for network facilities, you can use the SOCKET API section. This section will explain examples of APIs used for networking.
This chapter explains how to use the C programming language for networking purposes on a Linux machine.
Example of compiling and running a program:
# gcc --o program source.c
# ./program
Data Structure and Handling
Before using socket programming, a structure variable is needed to store information about the network. The structures needed include:
- sockaddr
- sockaddr_in.
Examples of its use are:
struct sockaddr { unsigned short sa_family; // address family, AF_xxx char sa_data[14]; // 14 bytes of protocol address
};
Where, sa_family is used to determine the type of family used in this chapter using AF_INET means using the INTERNETWORKING family. While for sa_data is used for information on the destination and port used.
To use this structure, one more structure is needed, namely sockadd_in, where "in" means internet.
struct sockaddr_in { short int sin_family; // Address family unsigned short int sin_port; // Port number struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr
};
With this structure, the programmer will easily control the data. In the sin_zero section, it is used as a complement where it must be set to a value of 0, this can be done using the memset() function.
To use an IP address, a structure variable is also needed, namely the in_addr structure, where the in_addr structure is as follows:
// Internet address (a structure for historical reasons) struct in_addr { unsigned long s_addr; // that's a 32-bit long, or 4 bytes
};
So that users can do it by creating an example variable ina and of the type struct sockaddr_in then ina.sin_addr.s_addr can be used as an object for the IP address.
1.1. Change of variables
The initial change that can be used is the change from short (2 bytes) to long (4 bytes). Then another change is the change from host to network. So that each change can be abbreviated into 1 letter, namely , s, l, n, and h.
Functions that can be used for these changes include:
- htons() : change host to network with short system
- htonl() : change host to network with long system
- ntohs() : network change to host with short system
- ntohl() : network change to host with long system.
1.2. IP address handling
There are several ways to enter an IP address into a variable in socket programming.
If we already have a variable struct sockadd_in ina, and we have an IP address of "10.252.102.23". Then with the inet_addr() function, we can change the IP address to an unsigned long. Example of use:
ina.sin_addr.s_addr = inet_addr("10.252.102.23");
Apart from that, there is another way, namely by using inet_aton:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
And an example of its use is as follows:
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order inet_aton("10.252.102.53", &(my_addr.sin_addr));
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
So if we want to display the contents of these variables, we can do this with the additional function inet_ntoa (network to ascii).
printf("%s", inet_ntoa(ina.sin_addr));
Complete example:
char *a1, *a2; . . a1 = inet_ntoa(ina1.sin_addr);
//this is 192.168.4.14 a2 = inet_ntoa(ina2.sin_addr);
// this is 10.12.110.57 printf("address 1: %s\n",a1);
printf("address 2: %s\n",a2);
will produce
address 1: 10.12.110.57 address 2: 10.12.110.57
Understanding Ports and Sockets
1. Port
Ports are used to perform communication processes with other processes on a TCP/IP network. Ports use 16-bit numbers, used for host-to-host communication. There are 2 types of ports, namely:
- Well-known: port that is already owned by the server. Example: telnet uses port 23. Well-known ports have a range from 1 to 1023. Well-known ports are regulated by the Internet Assigned Number Authority (IANA) and can be used by system processes with certain users who have access.
- Ephemeral: clients do not use well-known ports because to communicate with the server, they have already made an agreement in advance to use which port. Ephemeral ports have a range from 1023 to 65535.
For 1 port number cannot be used by 2 different applications at the same time.
2. Socket
The socket interface is part of the Application Programming Interface (API) which is used for communication protocols.
Terminology used:
- Socket is a special type of file handle, which is used by the operating system to access the network.
- The socket address is: <protocol, local address, local process> example:
<tcp, 193.44.234.3, 12345>
- Conversation: communication link between 2 processes
- Association: communication event between 2 processes <protocol, local-address, local-process, foreign-address, foreign-process> o Example:
<tcp, 193.44.234.4, 1500, 193.44.234.5, 21>
- Half-association:
< protocol, local-address, local-process>
or<protocol, foreign-address, foreign-process>
- Half-association is also called transport address.