Download Linux Sockets with TCP/IP communications

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Wake-on-LAN wikipedia , lookup

Distributed firewall wikipedia , lookup

Dynamic Host Configuration Protocol wikipedia , lookup

Airborne Networking wikipedia , lookup

Network tap wikipedia , lookup

AppleTalk wikipedia , lookup

Recursive InterNetwork Architecture (RINA) wikipedia , lookup

Remote Desktop Services wikipedia , lookup

Lag wikipedia , lookup

Piggybacking (Internet access) wikipedia , lookup

Parallel port wikipedia , lookup

List of wireless community networks by region wikipedia , lookup

Cracking of wireless networks wikipedia , lookup

Zero-configuration networking wikipedia , lookup

Transcript
Linux Sockets with TCP/IP communications
1. SOCKET -- create and open a socket
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int socket (int domain, int type, int protocol);
// domain is PF_INET (or in some cases AF_INIT) for a network socket
// type is SOCK_STREAM for TCP/IP
// protocol default (0) is TCP for SOCK_STREAM
// returns a file descriptor for a newly created and opened socket
This function creates a stream socket and opens a file descriptor. Socket does not block.
2. BIND -- associate a socket with an address and port
int bind (int sd, const struct sockaddr_in *p, int addr_len);
// sd is a file descriptor for an open socket
// p points to a sockaddr_in structure containing the port and address
// addr_len is the byte size of the sockaddr_in structure
// returns success (0) or failure (non-zero)
Bind associates a socket with a network address and a port to allow future connections requests. Bind does
not block. An attempt to connect to a port prior to the destination binding a socket to the port will result in the
connect() call failing.
3. CONNECT
int connect (int sd, const struct sockaddr_in *p, int addr_len);
// (see bind() for parameter descriptions)
// returns success or failure
Connect() attempts to establish a connection with another socket and blocks until an associated accept() is
executed on the destination. If the listen() queue has been exceeded, a connect request will fail.
4. LISTEN
int listen (int sd, int backlog_size);
// sd is an open socket file descriptor
// backlog_size is the number of connection requests that can be pending or queued without failing.
// return success or failure
Listen does not block.
5. ACCEPT
int accept (int sd, struct sockaddr_in *p, int *addr_lenp);
// sd is a file descriptor for an open socket
// p points to a sockaddr_in structure -- on return will contain info about the source making a connection.
// addr_lenp -- on return will contain the length of the source sockaddr_in structure
// returns an open file descriptor for a connected socket corresponding to an incoming connection request.
Accept recognizes the oldest pending connection request on a given socket file descriptor and returns a new
socket file descriptor that is connected to the requestor. As such, the requestor is actually handed off to a new
socket and the original socket is still available to listen and accept further connection requests from other
sources. Accept blocks if no connection request is queued.
6.
READ, WRITE, CLOSE
Once established, a socket file descriptor can be used with the standard POSIX interface – read(), write(),
and close(). Read() blocks until an incoming message is received. Messages are received in FIFO order. Unread
message bytes are left in the incoming buffer.
7. STRUCT SOCKADDR_IN (or the generic form STRUCT SOCKADDR)
struct sockaddr_in
{ short sin_family;
u_short sin_port;
struct in_addr sin_addr;
...
};
// network domain socket address structure
// PF_INET is the family for Linux TCP network sockets
// associated port number
// associated network address (containing s_addr)
The field sin_addr.s_addr may be set to INADDR_ANY by a listening process to accept connection
requests from any source network address. To specify an outgoing network address, use memcpy() to transfer
an address from a hostent structure (see below).
11. GETHOSTBYNAME
struct hostent *gethostbyname (const char *name);
// name is a string containing a text network address
// returns a pointer to a hostent structure containing corresponding numeric or canonical address
The function gethostbyname() uses a local name service to fill the hostent structure with address
information for a host with a textual network address specified by the character-string parameter name.
12. STRUCT HOSTENT
struct hostent
{ char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
};
// official name of host
// alias list
// host address type
// length of address
// list of addresses from name server
Socket communications use canonical network addresses, which are somewhat different from the text/dot
notation that is more human readable. The canonical network address filled into a hostent structure by
gethostbyname() may be copied into a s.addr field of a sockaddr_in structure with the following;
struct sockaddr mysocket;
struct hostent *p;
...
memcpy (&mysocket.sin_addr.s.addr, p->h_name, p->h_length);
13. DATA CONVERSIONS and other USEFUL FUNCTIONS
int ntohi (int x);
// convert a network-format integer to local format
long ntohl (long x);
// convert a network-format long to local format
int htoni (int x);
// convert a local-format int to network format
long htonl (long x);
// convert a local-format long to network format
char *inet_ntoa (struct in_addr sin_addr);
// convert a canonical network address to text/dot notation.
int getpeername (int sd, struct sockaddr_in *addr, int *addrlen); // fill the sockaddr_in structure with the
network information of the host connected to the other side of this port.
Client operation
1.
open a socket with socket()
2.
3.
2. connect the socket to an server’s internet port
read and write using the POSIX interface
close the socket
Example client
/* rclient.c test of remote client calls (no error detection for brevity) */
/*
/*
call with remote server host name and port number as arguments */
example: % rclient lab1.usu.edu 4321
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void main(int argc, char *argv[])
{ static struct hostent *hostp;
struct sockaddr_in name;
int sd;
char buf[64];
/* create an internet socket */
sd = socket (PF_INET, SOCK_STREAM, 0);
/* internet host information */
/* internet socket address */
/* internet domain stream */
/* now connect the socket to the right port and server host */
name.sin_family = PF_INET;
/* internet domain */
name.sin_port = atoi (argv[2]);
/* advertised port */
hostp = gethostbyname (argv[1]);
/* advertised host name */
memcpy (&name.sin_addr.s_addr, hostp->h_addr, hostp->h_length);
connect (sd, &name, sizeof(name));
/* now talk to the server... */
write (sd, “help!”, 6);
read (sd, buf, 64);
printf (“reply: %s\n”, buf);
close (sd);
}
Server operation
1.
2.
3.
4.
5.
6.
open a listening socket with socket()
bind the socket to a port for incoming requests
set the size of the listening queue for incoming connection requests with listen()
wait for then accept a connection request on a temporary port with accept()
read and write using the POSIX interface with the temporary port
close the sockets
Example server
/* server.c test of remote server (no error detection for brevity) */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORTNUM 4321
void main(int argc, char *argv[])
{ struct sockaddr_in name, *p;
struct sockaddr addr;
int sd, ld, addrlen;
char buf[64];
ld = socket (PF_INET, SOCK_STREAM, 0);
name.sin_family = PF_INET;
name.sin_port = PORTNUM;
name.sin_addr.s_addr = INADDR_ANY;
bind (ld, &name, sizeof(name));
printf (“Server listening on port %d\n”, PORTNUM);
listen (ld, 5);
addrlen = sizeof(addr);
p = (struct sockaddr_in *) &addr;
while (1)
{ sd = accept (ld, 0, 0);
getpeername (sd, &addr, &addrlen);
printf (“ call from: %s\n”, inet_ntoa(p->sin_addr));
read (sd, buf, sizeof(buf));
write (sd, “on the way”, 11);
close (sd);
}
}
Compilation:
% g++ -o client client.c –lsocket –lnsl
% g++ -o server server.c –lsocket –lnsl
Execution:
on machine labA.cs.usu.edu:
% server
on machine labB.cs.usu.edu:
% client labA.cs.usu.edu 4321
/* publicly advertised port number */
/* internet socket address */
/* generic socket address */
// listening socket for incoming connections
/* accept any incoming addr */
/* bind socket to port */
/* (just for demonstration) */
/* input service loop */
// sd is a temporary port for this connection only.
/* who’s calling? */