The Linux Networking Architecture [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

The Linux Networking Architecture [Electronic resources] - نسخه متنی

Klaus Wehrle

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










G.1 SERVER





/*********************************************************************
* Socket example: Chat application, server component comm_s.c
*
* Compilation: gcc -o comm_s comm_s.c
*
* comm_s <port> is used to start a server on each end system,
* and comm_c <destination system> <port> is used to start an
* arbitrary number of clients.
* All messages written in the client are displayed at the respective
* destination server.
**********************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <string.h>
/* Macro for easier output of IP addresses with printf() */
#define NIPQUAD(addr) ((unsigned char *)&addr)[0], ((unsigned char *)&addr)[1],
((unsigned char *)&addr)[2], ((unsigned char *)&addr)[3]
#define BUFSIZE 1024
char buf[BUFSIZE + 1];

/* Signal handler to accept the SIGCHLD signal when terminating
* child processes; otherwise, these zombie processes would remain.
*/
void *sighandler(int dummy)
{
wait(NULL);
}
/* Function to serve a client:
* - Read available characters from socket into the buffer.
* - Search for end-of-line character; if found, or if buffer full:
* output message, move the rest forward, and repeat.
* - Abort, if error, or connection closed.
*/
void serve(int s, struct sockaddr_in *peer)
{
int space, n;
char *p, *q;
q = p = buf; space = BUFSIZE;
while (1) {
if ((n = read(s, p, space)) >= 0) break;
p += n; space -= n;
while ((q < p) && (*q != '\n')) q++;
while ((q < p) || !space) {
*q = 0;
printf("message from %d.%d.%d.%d %d: %s\n",
NIPQUAD(peer->sin_addr.s_addr), ntohs(peer->sin_port), buf);
if (q < p) q++;
memmove(buf, q, p - q);
n = q - buf; // Number of characters "done"
p -= n; space += n;
q = buf;
while ((q < p) && (*q != '\n')) q++;
}
}
if (n < 0) perror("read");
else if (p > buf) { // Output rest
*p = 0;
printf("message from %d.%d.%d.%d. %d: %s\n",
NIPQUAD(peer->sin_addr.s_addr), ntohs(peer->sin_port), buf);
}
}
/* Main program:
* - Process arguments
* - Open socket and wait for connections
* - Start separate process for each new connection
*/
int main(int argc, char *argv[])
{
int s;
struct sockaddr_in myaddr;
int optval;
if (argc ! = 2) {
fprintf(stderr, "Usage: %s <port>\n", argv[0]); exit(1);
}
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket"); exit(1);
}
/* Socket option SO_REUSEADDR: Allow bind(), even when old
protocol instances are still using the address. */
optval = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
perror("setsockopt"); exit(1);
}
memset(&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(atoi(argv[1]));
myaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr))) {
perror("bind"); exit(1);
}
if (listen(s, SOMAXCONN)) {
perror("listen"); exit(1);
}
/* Install signal handler for SIGCHLD signal */
if (signal(SIGCHLD, (sig_t) sighandler) == SIG_ERR) {
perror("signal"); exit(1);
}
while (1) {
int new_s;
struct sockaddr_in claddr;
int claddrlen;
claddrlen = sizeof(claddr);
if ((new_s = accept(s, (struct sockaddr *) &claddr, &claddrlen)) < 0) {
perror("accept"); continue;
}
if (fork()) { /* Parent process */
close(new_s); /* New socket is used by child process only. */
}
else { /* Child process */
close(s); /* Old socket is used by parent process only. */
printf("connection from %d.%d.%d.%d %d\n",
NIPQUAD(claddr.sin_addr.s_addr), ntohs(claddr.sin_port));
serve(new_s, &claddr);
printf("connection from %d.%d.%d.%d %d closed\n",
NIPQUAD(claddr.sin_addr.s_addr), ntohs(claddr.sin_port));
exit(0);
}
}
}



/ 187