socket programming.

advertisement
back to Communication
Nezer J. Zaidenberg
(Evyatar’s version)
Remember to read Beej’s guides
what we should know
using TCP sockets
socket(2), close(2)
bind(2)+listen(2)+accept(2)
connect(2)
send(2)+recv(2)
select(2)
Protecting recv(2)
unless we select(2) before recv(2) we
end up with process that does busy
waiting (check.)
Therefore, all our recv’s should be
protected by select even if alone.
Busy Waiting..
Datagram sockets
Just forget everything you learned about TCP
sockets.
DATAGRAM SOCKETS
Datagram sockets are
CONNECTIONLESS. (there are
connected udp sockets in Linux but we
will not discuss)
NO CONNECT(2), LISTEN(2),
ACCEPT(2)
So what do we have left?
Server still calls socket(2) and bind(2) to
catch a port.
Client still calls socket(2)
No connection - problem
when we used TCP sockets we called
send(2)+recv(2) and we knew who to
send to because this was already in the
socket file descriptor....
when we don’t have connection this
information is no longer available to us
Sendto(2) + recvfrom(2)
works like send(2)+recv(2) but also
specify the address we send and recv
from.
•
SEND(2) BSD System Calls Manual SEND(2)
•
NAME
•
•
sendto -- send a message from a socket
SYNOPSIS
•
#include <sys/socket.h>
•
ssize_t
•
sendto(int socket, const void *buffer, size_t
length, int flags, const struct sockaddr
*dest_addr, socklen_t dest_len);
•
RECV(2) BSD System Calls Manual
•
NAME
•
•
recvfrom-- receive a message from a socket
SYNOPSIS
•
#include <sys/socket.h>
•
ssize_t
•
RECV(2)
recvfrom(int socket, void *restrict buffer, size_t
length, int flags, struct sockaddr *restrict address,
socklen_t *restrict address_len);
Explaining
both functions return bytes received
while holding max buffer size as
argument.
The additional sockaddr is the address
we “would connect to”.
As always we will “inherit” and use
sockaddr_in or sockaddr_un.
silly UDP talker - from beej
•
int main(int argc, char *argv[])
•
{
•
int sockfd;
•
struct addrinfo hints, *p;
•
int rv,numbytes;
•
memset(&hints, 0, sizeof hints);
•
hints.ai_family = AF_UNSPEC;
•
hints.ai_socktype = SOCK_DGRAM;
Talker continued
Later
•
getaddrinfo(argv[1], SERVERPORT, &hints, &p)
•
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)
•
sendto(sockfd, argv[2], strlen(argv[2]), 0,
p->ai_addr, p->ai_addrlen)
•
•
freeaddrinfo(p);
•
printf("talker: sent %d bytes to %s\n", numbytes, argv[1]);
•
close(sockfd);
•
return 0;
•
}
Please examine Beej
for UDP listener
http://www.beej.us/guide/bgnet/output/html/
multipage/clientserver.html#datagram
UNIX domain sockets
As we said previously very similar to
Internet sockets
We don’t use ports. instead we use path
to find the right application. (we create a
dummy “file” as address)
We will not cover the commands again
but go over change list
UDS changes
in socket
we use AF_UNIX for domain
In bind
we use struct sockaddr_un
we use AF_UNIX for domain
we use path instead of port
UDS changes
no changes in listen(2) accept(2)
send(2) recv(2) close(2) (accept return
address as sockaddr_un)
sendto(2) and recvfrom(2) use struct
sockaddr_un instead of struct
sockaddr_in
UDS bind example
•
local.sun_family = AF_UNIX;
•
strcpy(local.sun_path, SOCK_PATH);
•
unlink(local.sun_path);
•
len=strlen(local.sun_path)+sizeof(local.sun_family)
;
•
if (bind(s, (struct sockaddr *)&local, len) == -1) {
perror("bind");
exit(1);
•
•
}
about example
in the above example unlink(2) deletes
the file if it exist (from previous run)
otherwise bind will fail.
full example -
http://beej.us/guide/bgipc/output/html/
multipage/unixsock.html
good luck with HW1
note regarding HW1
you have been requested to handle
connections in a child process.
After accept(2) you should fork(2) and
use the new child process to handle the
connection. (father can close(2) newfd)
Child exit(2) when the connection is
closed(2)
And if we still have time…
socketpair(2)
socketpair(2) system call create two
sockets that are already connected!
This is useful way for father and child
process to communicate
•
SOCKETPAIR(2)
•
NAME
•
socketpair -- create a pair of connected
sockets
•
SYNOPSIS
•
#include <sys/socket.h>
•
int
•
socketpair(int domain, int type, int protocol, int
socket_vector[2]);
Explaining
the first 3 parameters are same as
socket(2) and define the socket type to
be created
the last parameter is an int array with
file descriptors of the connected sockets
return value is just success/fail
usage example
•
int sv[2]; /* the pair of socket
descriptors */
•
if (socketpair(AF_UNIX,
SOCK_STREAM, 0, sv) == -1) {
•
perror("socketpair");
•
exit(1);
•
}
Download