Socket Programming Question:
Explain with a Connection-Oriented Example - listen(), accept()?
Answer:
/* Generic program structure for establishing
connection-oriented client-server environment.
*/
/* server program */
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
struct sockaddr myname;
char buf[80];
main()
{
int sock, new_sd, adrlen, cnt;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
printf("server socket failure %dn", errno);
perror("server: ");
exit(1);
}
myname.sa_family = AF_UNIX;
strcpy(myname.sa_data, "/tmp/billb");
adrlen = strlen(myname.sa_data) +
sizeof(myname.sa_family);
unlink("/tmp/billb"); /* defensive programming */
if (bind(sock, &myname, adrlen) < 0) {
printf("server bind failure %dn", errno);
perror("server: ");
exit(1);
}
if (listen(sock, 5) < 0 {
printf("server listen failure %dn", errno);
perror("server: ");
exit(1);
}
/* Ignore child process termination. */
signal (SIGCHLD, SIG_IGN);
/* Place the server in an infinite loop, waiting
on connection requests to come from clients.
In practice, there would need to be a clean
way to terminate this process, but for now it
will simply stay resident until terminated by
the starting terminal or the super-user. */
while (1) {
if (new_sd = accept(sock,
&myname, &adrlen)) < 0 {
printf("server accept failure %dn", errno);
perror("server: ");
exit(1);
}
/* Create child server process. Parent does no
further processing -- it loops back to wait
for another connection request. */
printf("Socket address in server %d is %x, %sn",
getpid(), myname.sa_data, myname.sa_data);
if (fork() == 0) { /* child process */
close (sock); /* child does not need it */
/* . . . . . */
cnt = read(new_sd, buf, strlen(buf));
printf ("Server with pid %d got message %sn",
getpid(), buf);
strcpy (buf, "Message to client");
cnt = write(new_sd, buf, strlen(buf));
printf("Socket address in server %d is %x, %sn",
getpid(), myname.sa_data, myname.sa_data);
/* . . . . . */
close (new_sd); /* close prior to exiting */
exit(0);
} /* closing bracket for if (fork() ... ) */
} /* closing bracket for while (1) ... ) */
} /* closing bracket for main procedure */
/* client program */
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
char buf[80];
struct sockaddr myname;
main()
{
int sock, adrlen, cnt;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
printf("client socket failure %dn", errno);
perror("client: ");
exit(1);
}
myname.sa_family = AF_UNIX;
strcpy(myname.sa_data, "/tmp/billb");
adrlen = strlen(myname.sa_data) +
sizeof(myname.sa_family);
if (connect( sock, &myname, adrlen) < 0) {
printf("client connect failure %dn", errno);
perror("client: ");
exit(1);
}
/* . . . . . */
strcpy(buf, "Message sent to server");
cnt = write(sock, buf, strlen(buf));
cnt = read(sock, buf, strlen(buf));
printf("Client with pid %d got message %sn",
getpid(), buf);
printf("Socket address in server %d is %x, %sn",
getpid(), myname.sa_data, myname.sa_data);
/* . . . . . */
exit(0);
}
connection-oriented client-server environment.
*/
/* server program */
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
struct sockaddr myname;
char buf[80];
main()
{
int sock, new_sd, adrlen, cnt;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
printf("server socket failure %dn", errno);
perror("server: ");
exit(1);
}
myname.sa_family = AF_UNIX;
strcpy(myname.sa_data, "/tmp/billb");
adrlen = strlen(myname.sa_data) +
sizeof(myname.sa_family);
unlink("/tmp/billb"); /* defensive programming */
if (bind(sock, &myname, adrlen) < 0) {
printf("server bind failure %dn", errno);
perror("server: ");
exit(1);
}
if (listen(sock, 5) < 0 {
printf("server listen failure %dn", errno);
perror("server: ");
exit(1);
}
/* Ignore child process termination. */
signal (SIGCHLD, SIG_IGN);
/* Place the server in an infinite loop, waiting
on connection requests to come from clients.
In practice, there would need to be a clean
way to terminate this process, but for now it
will simply stay resident until terminated by
the starting terminal or the super-user. */
while (1) {
if (new_sd = accept(sock,
&myname, &adrlen)) < 0 {
printf("server accept failure %dn", errno);
perror("server: ");
exit(1);
}
/* Create child server process. Parent does no
further processing -- it loops back to wait
for another connection request. */
printf("Socket address in server %d is %x, %sn",
getpid(), myname.sa_data, myname.sa_data);
if (fork() == 0) { /* child process */
close (sock); /* child does not need it */
/* . . . . . */
cnt = read(new_sd, buf, strlen(buf));
printf ("Server with pid %d got message %sn",
getpid(), buf);
strcpy (buf, "Message to client");
cnt = write(new_sd, buf, strlen(buf));
printf("Socket address in server %d is %x, %sn",
getpid(), myname.sa_data, myname.sa_data);
/* . . . . . */
close (new_sd); /* close prior to exiting */
exit(0);
} /* closing bracket for if (fork() ... ) */
} /* closing bracket for while (1) ... ) */
} /* closing bracket for main procedure */
/* client program */
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
char buf[80];
struct sockaddr myname;
main()
{
int sock, adrlen, cnt;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
printf("client socket failure %dn", errno);
perror("client: ");
exit(1);
}
myname.sa_family = AF_UNIX;
strcpy(myname.sa_data, "/tmp/billb");
adrlen = strlen(myname.sa_data) +
sizeof(myname.sa_family);
if (connect( sock, &myname, adrlen) < 0) {
printf("client connect failure %dn", errno);
perror("client: ");
exit(1);
}
/* . . . . . */
strcpy(buf, "Message sent to server");
cnt = write(sock, buf, strlen(buf));
cnt = read(sock, buf, strlen(buf));
printf("Client with pid %d got message %sn",
getpid(), buf);
printf("Socket address in server %d is %x, %sn",
getpid(), myname.sa_data, myname.sa_data);
/* . . . . . */
exit(0);
}
Previous Question | Next Question |
Explain Data Transfer over Connected Sockets - send() and recv()? | What is the IP Address? |