Berkeley Sockets An example - PowerPoint PPT Presentation

1 / 20
About This Presentation
Title:

Berkeley Sockets An example

Description:

fprintf(stderr,'Usage: %s port number n', argv[0]); exit(1) ... listen_socket = TCPListenSocket(atoi(argv[1])); /* Connect pairs of clients forever ... – PowerPoint PPT presentation

Number of Views:260
Avg rating:3.0/5.0
Slides: 21
Provided by: ola5
Category:

less

Transcript and Presenter's Notes

Title: Berkeley Sockets An example


1
Berkeley Sockets An example
  • Carsten Griwodz
  • (adapted from lecture by Olav Lysne)

2
Read and Write
  • The call read(sock, buffer, n)
  • Reads n characters
  • From socket sock
  • Stores them in the character array buffer
  • The call write(sock, buffer, n)
  • Writes n characters
  • From character array buffer
  • To the socket sock

3
Read and Write in TCP
TCP sender
  • Typical
  • retval -1
  • Some kind of error, look at errno
  • Retval 0
  • The connection has been closed
  • Retval n lt 2000
  • You tried to send too fast
  • Only n bytes have been sent
  • Try sending the reset
  • Retval 2000
  • All bytes have been sent
  • Very untypical
  • Retval lt -1
  • Retval gt 2000
  • Both cases
  • Have you used char retval instead of int retval?

char buffer2000 int retval buffer0
a buffer1 b buffer2 c /
write abcdefghij / retval write( sock, buffer,
2000 )
4
Read and Write in TCP
TCP receiver
  • Typical
  • retval -1
  • Some kind of error, look at errno
  • Retval 0
  • The connection has been closed
  • Retval n lt 2000
  • Only n bytes have been received
  • No new data has arrived recently
  • Try sending the rest
  • Retval 2000
  • All bytes have been received
  • Very untypical
  • Retval lt -1
  • Retval gt 2000
  • Both cases
  • Have you used char retval instead of int retval?

char buffer2000 int retval / write
abcdefghij / retval read( sock, buffer, 2000 )
5
Application protocol chatting
Chat client 1
Chat server
Chat client 2
connection
chat
chat
chat

disconnection
6
Some detail
  • Port numbers are sent as 4 ASCII characters
  • Machine names are sent as
  • First 2 ASCII characters as a two digits decimal
    number indicating the number of bytes in the name
  • Then the name, in the number of bytes indicated
    before
  • A chatted line is sent as 80 ASCII characters
  • When a user chats a line that starts with the
    character the chat session ends

7
Helper function for communication
  • It is worthwhile to put some socket functions
    into functions calls such that it becomes easier
    to use them
  • A call that provides a socket that listens to a
    given port
  • Hides bind, listen, struct sockaddr_in
  • A call that provides a socket that is connection
    to a given hostname and port number
  • Hides connect, name resolution, etc.
  • Several read and write operations

8
Creation of a listen socket
/ Allow that the socket to reuse a port that
the server has also used when it was
started before. Otherwise TCP waits for a
few minutes before allowing reuse. / i 1
setsockopt( request_sock, SOL_SOCKET,
SO_REUSEADDR, i, sizeof(i)) /
Bind the address to the socket. / if
(bind(request_sock, (struct sockaddr
)serveraddr, sizeof serveraddr) lt 0)
printf("Binding address to socket
failed\n") exit(1) / Start
listening to the socket / if
(listen(request_sock, SOMAXCONN) lt 0)
printf("Can't listen to the socket\n")
exit(1) return request_sock
int TCPListenSocket(int port_number) struct
sockaddr_in serveraddr, clientaddr int
clientaddrlen int request_sock int i
/ Create the request socket. /
request_sock socket(AF_INET, SOCK_STREAM,
IPPROTO_TCP) if
(request_sock lt 0) printf("Creation
of a socket failed.\n") exit(1)
/ Fill in the address structure /
bzero((void ) serveraddr, sizeof(serveraddr))
serveraddr.sin_family AF_INET
serveraddr.sin_addr.s_addr INADDR_ANY
serveraddr.sin_port htons(port_number)
9
Connection from the client side
int TCPClientSocket(char machine, int
port_number) struct hostent hostp
struct sockaddr_in serveraddr int sock
/ Create a socket / if ((sock
socket(AF_INET, SOCK_STREAM,
IPPROTO_TCP)) lt 0)
printf("Creation of a socket failed.\n")
exit(1) / Clean the serveraddr
structure / bzero((void ) serveraddr,
sizeof(serveraddr)) / Initialize the
serveraddr structure for the machine and port /
serveraddr.sin_family AF_INET
/ Look in DNS for the IP address of the name
/ if ((hostp gethostbyname(machine))
0) fprintf(stderr,"Ukjent machine
s\n",machine) exit(1) / Put
the address into the serveraddr structure /
memcpy(serveraddr.sin_addr,
hostp-gth_addr, hostp-gth_length) / Add the
port number / serveraddr.sin_port
htons(port_number) / Connect to the other
machine / if (connect(sock, (struct sockaddr
)serveraddr,
sizeof serveraddr) lt 0)
close(sock) printf("Can't connect to
s\n",machine) exit(1) return
sock
10
Safe reading and writing
/ Reads exactly l bytes from the socket / int
saferead(int so, char buf, int l) int i
for (i0 iltl i)
bufisafereadbyte(so) return l /
Write to a socket in the same way as write, but
returns an error message if the socket has been
closed in the meantime / int safewrite(int so,
char buf, int l) int i if
(iwrite(so, buf, l)0)
printf("Can't write to socket, connection is
closed" ) exit(1) return i
/ Reads exactly one byte from a socket
connection / char safereadbyte(int so) int
bytes char buf1 bytes read(so, buf,
1) / Check whether the read worked /
if (byteslt0) perror("Error in
saferead") if (close(so))
perror("close") exit(1) /
Check whether the connection is still open /
if (bytes0) printf("server end
of file on d\n",so) if (close(so))
perror("close") exit(1)
return buf0
11
Server connecting two clients
int connect_two_clients(int listen_socket)
int client_socket1, client_socket2 struct
sockaddr_in clientaddr1, clientaddr2 int
clientaddrlen1, clientaddrlen2 char
client_name180, client_name280 char
client_port15, client_port25 char
name_length13, name_length23 memset(
client_name1, 0, 80 ) memset( client_name2,
0, 80 ) memset( client_port1, 0, 5 )
memset( client_port2, 0, 5 ) memset(
name_length1, 0, 3 ) memset( name_length2,
0, 3 ) / Accept a connection from a first
client / clientaddrlen1 sizeof(clientaddr1)
client_socket1 accept(listen_socket,
(struct sockaddr )clientaddr1,
clientaddrlen1) if (client_socket1 lt 0)
perror("Can't accept connection from a first
chat client\n" )
/ Read machine name and port number that
client sends as its contact information
/ saferead(client_socket1, name_length1,
2) saferead(client_socket1, client_name1,
atoi(name_length1)) saferead(client_socket1,
client_port1, 4) / Accept a connection
from second client / clientaddrlen2
sizeof(clientaddr2) client_socket2
accept(listen_socket,
(struct sockaddr )clientaddr2,
clientaddrlen2) if (client_socket2 lt 0)
perror("Can't accept connection from a
second chat client\n" ) / Read machine
name and port number that client sends as
its contact information / saferead(client_soc
ket2, name_length2, 2) saferead(client_socket
2, client_name2, atoi(name_length2))
saferead(client_socket2, client_port2, 4)
12
Server connecting two clients cntd.
/ Tell the first client that it is the
server in the chat connection, and to wait
for connection by a chat partner /
safewrite(client_socket1, "T", 1) / Tell
the second client that it is the client in the
chat connection, and to connect to the
given name and port / safewrite(client_socket
2, "K", 1) safewrite(client_socket2,
name_length1, 2) safewrite(client_socket2,
client_name1, atoi(name_length1))
safewrite(client_socket2, client_port1, 4)
/ Close the sockets for both clients /
close(client_socket1) close(client_socket2)
return 0
13
Servers main function
int main(int argc, char argv) int
listen_socket if( argc ! 2 )
fprintf(stderr,"Usage s ltport numbergt\n",
argv0) exit(1) / Start
listening to the port number from the command
line / listen_socket TCPListenSocket(ato
i(argv1)) / Connect pairs of clients
forever / while (1) connect_two_clients(liste
n_socket) / We don't ever come here /
close(listen_socket)
14
Client contacting the server
/ Connect to a chat server / sock
TCPClientSocket(servername,atoi(serverport))
/ Tell the server how you can be contacted by a
chat partner / sprintf(name_length,
"d", strlen(myname)) safewrite(sock,
name_length, 2) safewrite(sock, myname,
strlen(myname)) safewrite(sock, myport,
4) / Receive from the server whether you
will act as a client or as a server in the
chat / saferead(sock, client_or_server, 1)
int getchatpartner( char servername, char
serverport, char
myname, char myport ) int sock,
listen_socket, partneraddresslength struct
sockaddr partneraddress char
name_length3 char client_or_server2
char chatpartnername80 char
chatpartnerport5 char buf80
memset( name_length, 0, 3 ) memset(
client_or_server, 0, 2 ) memset(
chatpartnername, 0, 80 ) memset(
chatpartnerport, 0, 5 ) / Create a socket
that is read to accept connections from a
chat partner / listen_socket
TCPListenSocket(atoi(myport))
15
Client contacting the server cntd.
else / Act as the server in
the chat, no more information is coming from
the server / close(sock) /
Accept a connection from a chat partner /
partneraddresslength sizeof(partneraddress)
sock accept(listen_socket,
(struct sockaddr )partneraddress,
partneraddresslength)
if (sock lt 0) perror("Error
accepting connection from chat partner" )
/ Write to the screen that the chat partner
talks first / printf("Connection create,
partner talks first!!\n") saferead(sock,
buf,80) printf(buf) return
sock
if (client_or_server0 'K')
/ You will be the client in the chat /
/ Close the socket that you would have
needed as a chat server /
close(listen_socket) / Read the length
of the chat partner's hostname /
saferead(sock, name_length, 2) / Read
the chat partner's hostname /
saferead(sock, chatpartnername,
atoi(name_length)) / Read the chat
partner's port number / saferead(sock,
chatpartnerport, 4) / Close the
connection to the server /
close(sock) / Connect to the chat
partner / sock TCPClientSocket(chatpart
nername,
atoi(chatpartnerport)) / Write to
the screen that the user can talk first /
printf("Connection create, you talk
first!!\n")
16
Client chatting and main
int main(int argc, char argv) int sock
if( argc ! 5 ) fprintf( stderr,
"Usage s ltservernamegt ltserverportgt
ltmynamegt ltmyportgt\n", argv0)
exit(1) / ask for a chart partner /
sock getchatpartner(argv1, argv2, argv3,
argv4) / chat along!/ chat(sock) /
Close the chat socket / close(sock)
/ A function that alternately reads a text
string from standard input and sends it over
the TCP connection, and receive a text string
and prints it on the screen. / int chat(int
socket) char text80 while (1)
fgets(text,80,stdin)
write(socket,text, 80) if (text0'')
return 0 saferead(socket, text,80)
if (text0'') return 0
printf(text)
17
Weaksnesses of the implementation
  • Server accounts hardly for wrong client behaviour
  • Sending characters when a post number is required
  • Client connects but does not send data, chat
    server ends
  • Server forwards simple what it receives, without
    checking that the machine name is the calling
    clients
  • Chat client can only send in turns
  • That is different in a real chat session, or in
    real life
  • Everything that is typed should be sent, without
    an understanding of turns
  • Much more!

18
getchatpartner begins as before
/ Connect to a chat server / sock
TCPClientSocket(servername,atoi(serverport))
/ Tell the server how you can be contacted by a
chat partner / sprintf(name_length,
"d", strlen(myname)) safewrite(sock,
name_length, 2) safewrite(sock, myname,
strlen(myname)) safewrite(sock, myport,
4) / Receive from the server whether you
will act as a client or as a server in the
chat / saferead(sock, client_or_server, 1)
int getchatpartner( char servername, char
serverport, char
myname, char myport ) int sock,
listen_socket, partneraddresslength struct
sockaddr partneraddress char
name_length3 char client_or_server2
char chatpartnername80 char
chatpartnerport5 char buf80
memset( name_length, 0, 3 ) memset(
client_or_server, 0, 2 ) memset(
chatpartnername, 0, 80 ) memset(
chatpartnerport, 0, 5 ) / Create a socket
that is read to accept connections from a
chat partner / listen_socket
TCPListenSocket(atoi(myport))
19
...buts ends differently
else / Act as the server in the
chat, no more information is coming
from the server / close(sock)
/ Accept a connection from a chat partner /
partneraddresslength sizeof(partneraddress)
sock accept(listen_socket,
(struct sockaddr
)partneraddress,
partneraddresslength) if (sock lt 0)
perror("Error accepting connection from
chat partner" ) printf("Connection
create, chat along!!\n") return sock
if (client_or_server0 'K')
/ You will be the client in the chat /
/ Close the socket that you would have needed
as a chat server /
close(listen_socket) / Read the length
of the chat partner's hostname /
saferead(sock, name_length, 2) / Read
the chat partner's hostname /
saferead(sock, chatpartnername,
atoi(name_length)) / Read the chat
partner's port number / saferead(sock,
chatpartnerport, 4) / Close the
connection to the server /
close(sock) / Connect to the chat
partner / sock TCPClientSocket(chatpart
nername,
atoi(chatpartnerport))
20
chat function used separate processes for
reading and writing, so that the dont block each
other
int main(int argc, char argv) int
sock / get a chat partner / sock
getchatpartner(argv1, argv2, argv3,
argv4) / start chatting /
chat(sock) / close the chat socket /
close(sock)
int chat(int socket) int status char
text10 if (safefork()0) while
(text0 ! '')
fgets(text,80,stdin)
write(socket,text, 80) else
while (text0 ! '')
saferead(socket, text,80)
printf(text)
Write a Comment
User Comments (0)
About PowerShow.com