280 likes | 403 Views
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).
E N D
back to Communication • Nezer J. Zaidenberg (Evyatar’s version)
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.
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 RECV(2) • NAME • recvfrom-- receive a message from a socket • SYNOPSIS • #include <sys/socket.h> • ssize_t • 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
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)
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); • }