/* serverteman.c */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define KONEKSI_MAKSIMAL 10

int main (int argc, char *argv[])
{
struct sockaddr_in alamat_serv;
struct sockaddr_in alamat_clie;
unsigned no_port;
int socketfd;

if (argc != 2) {
fprintf (stderr, "gunakan: %s <nomor_port>\n", argv[0]);
exit(1);
}

no_port = atoi (argv[1]);

socketfd = socket (AF_INET, SOCK_STREAM, 0);

/* untuk membersihkan child process,
yang telah selesai */
signal(SIGCHLD, SIG_IGN);

/* kita reset terlebih dahulu variable alamat_serv */
bzero (&alamat_serv, sizeof(alamat_serv));
alamat_serv.sin_family = AF_INET;
alamat_serv.sin_port = htons (no_port);
/* macro INADDR_ANY menghasilkan current ip */
alamat_serv.sin_addr.s_addr = htonl (INADDR_ANY);

/* buka port */
if (bind (socketfd, (struct sockaddr *)&alamat_serv, sizeof (struct sockaddr)) < 0) {
fprintf (stderr, "maaf ya, tidak bisa memasang port !\n");
exit(1);
}

printf ("serverteman menunggu teman datang ...\n");

/* menuggu koneksi yang masuk,
* koneksi maksimal dilayani sebanyak KONEKSI_MAKSIMAL
*/
listen (socketfd, KONEKSI_MAKSIMAL);

while(1) {
int client_size = sizeof (struct sockaddr_in);
int newfd;

/* menerima koneksi yang datang */
newfd =accept (socketfd, (struct sockaddr *)&alamat_clie, &client_size);
if(newfd == -1) {
perror ("accept");
/* jika terjadi error akan looping lagi */
continue;
}

/* mengetahui siapa yang mengadakan koneksi */
printf("Teman dari %s telah datang\n", inet_ntoa (alamat_clie.sin_addr));

/* fork mengasilkan nilai return 0 pada child process,
pada parent process, fork() menghasilkan nilai pid dari child yang diciptakan*/

if (!fork ()) {
/* child process */

/* peringatan !, variabel buffer hanya menampung 255 karakter */
char buffer[256];

sprintf (buffer, "Halo Teman, selamat datang di Server.Teman\n");

/* kirim pesan */
if (send (newfd, buffer, strlen (buffer), 0) == -1) {
perror ("send");
continue;
}
close (newfd);
exit (0);
}
else
/* parent process,
disini tidak dibutuhkan newfd, jadi sebaiknya ditutup.
parent process akan looping lagi untuk menerima client yang lain*/
close (newfd);
}

return 0;
}
