You are on page 1of 116

Network Programming

C:\Documents and Settings\Administrator\Desktop\slc.jpg


Hands
on
Lab

September 2011

Information in this document, including URL and other Internet Web site referenc
es, is
subject to change without notice. This document supports a preliminary release o
f software
that may be changed substantially prior to final commercial release, and is the
proprietary
information of Binus University.

This document is for informational purposes only. BINUS UNIVERSITY MAKES NO


WARRANTIES, EITHER EXPRESS OR IMPLIED, AS TO THE INFORMATION IN THIS
DOCUMENT.

The entire risk of the use or the results from the use of this document remains
with the
user. Complying with all applicable copyright laws is the responsibility of the
user. Without
limiting the rights under copyright, no part of this document may be reproduced,
stored in
or introduced into a retrieval system, or transmitted in any form or by any mean
s
(electronic, mechanical, photocopying, recording, or otherwise), or for any purp
ose, without
the express written permission of Binus University.

Binus University may have patents, patent applications, trademarks, copyrights,


or other
intellectual property rights covering subject matter in this document. Except as
expressly
provided in any written license agreement from Binus University, the furnishing
of this
document does not give you any license to these patents, trademarks, copyrights,
or other
intellectual property.

Unless otherwise noted, the example companies, organizations, products, domain n


ames, email addresses, logos, people, places and events depicted herein are fictitious,
and no
association with any real company, organization, product, domain name, email add
ress,
logo, person, place or event is intended or should be inferred.

2011 Binus University. All rights reserved.

The names of actual companies and products mentioned herein may be the trademark
s of
their respective owners.

Table of Contents
OVERVIEW .......................................................................
............................................... iii
Chapter 01 Introduction to Network Programming .................................
.......................... 1
Chapter 02 Introduction to I/O Multiplexing and Non Blocking System ............
............ 11
Chapter 03 Program Client - Server .............................................
.................................... 22
Chapter 04 Advance Program Client - Server .....................................
............................. 36
Chapter 05 Client
Server with Broadcast ........................................
.............................. 46
Chapter 06 Client Server with Winsock ..........................................
................................. 55

OVERVIEW

Chapter 01
Introduction to Network Programming

Chapter 02
Introduction to I/O Multiplexing and Non Blocking System

Chapter 03
Program Client - Server

Chapter 04
Advance Program Client - Server

Chapter 05
Client Server with Broadcast

Chapter 06
. Client Server with WinSock

Chapter 01
Introduction to Network Programming

Objective:
.
.
.
.
.
.
.
.

Network Programming Objectives


Definisi Program Client Server
ARPANET
OSI 7 Layer
TCP/IP
Pemrograman Network Programming
Winsock Programming
I/O Model

Learning Outcomes:
. Memilih teknik dan protocol pemrogram jaringan untuk pemecahan suatu masalah
. Memperhitungkan beberapa program dengan protokol yang umum dipergunakan pada
jaringan komputer.
. Menjelaskan berbagai macam komponen yang berhubungan dengan pemrograman jaring
an

1.1. Network Programming Objectives

Pemrograman berbasis jaringan (network programming) memiliki tujuan untuk


mencapai:
1. Communication Medium
2. Resource Sharing

Communication medium artinya sebagai media komunikasi seperti :


1. E-mail (Electronic mail)
2. Chat
3. Workgroup Scheduling

Resources sharing artinya sebagi media sharing perangkat seperti :


1.
2.
3.
4.
5.

Database Server
Printer
Modem
Fax
Server Data

1.2. Definisi Program Client-Server

Program client-server adalah suatu program yang terdiri dari client dan server.
Server disini bekerja sebagai penyedia resources, sedangkan client adalah pihak
yang
merequest/meminta resources.

Server
(listen)

Client
Request
via
Port

Server

Client
Response
via
Port
Client Server Definition

Menurut Microsoft Encarta, servicing requests from others: describes a computer


network in which processing is divided between a client program running on a use
r s
machine and a network server program. One server can provide data to, or perform
storage-intensive processing tasks in conjunction with, one or more clients.

Client umumnya/pada dasarnya adalah suatu program yang terkoneksi pada satu
server, sedangkan server merupakan program yang menampung koneksi dari banyak
client.
(pengertian awam)

Gambarannya pada sistem client-socket adalah sebagai berikut:

[Server may handling multiple clients at the same time]


Server berdasarkan cara kerjanya dapat dibagi menjadi 2 bagian:
1. Concurrent Server
2. Iterative Server

Concurrent Server adalah server yang dapat menghandle banyak server dan memberik
an
response terhadap request yang ada secara bersamaan (concurrent).

Iterative Server adalah server yang dapat menghandle banyak server dan memberika
n
response terhadap request yang ada satu per satu (per client request)

Pada umumnya client dan server menggunakan basis TCP dan UDP walaupun ada
kemungkinan menggunakan protokol lain seperti RTMP, FTP, dll.

Berdasarkan pada sifatnya koneksi utama dibagi menjadi 2:


1. TCP ( RFC 793 by John Postel )
2. UDP ( RFC 768 by John Postel )

TCP ( Transmission Control Protocol ) bersifat connection-oriented


sedangkan UDP ( User Datagram Protocol ) bersifat connection-less.

TCP umumnya menggunakan koneksi full-duplex, untuk melakukan pengecekan status


koneksi. Pengecekan dilakukan bertahap (pertama kali dilakukan koneksi terlebih
dahulu,
baru data sebenarnya di transfer, kemudian baru di terminate). Itulah TCP lebih
reliable/dipercaya untuk koneksi-koneksi seperti World Wide Web, email, remote
administration and file transfer.

UDP merupakan protokol yang berjalan di layer transport (layer 4 OSI) yang bersi
fat
sederhana yang dideskripsikan pada Data yang dikirim bersifat datagram yang memi
liki
panjang seperti record. Pengecekan data sukses tidaknya hanya menggunakan checks
um
sehingga kurang reliable.

Interface tahapannya adalah (berikut analogi):


. Socket : Persiapkan colokan telepon dan teleponnya
. Bind : Pasangkan kabel telepon ke jack telepon
. Listen : Aktifkan telepon
. Connect : Menghubungi (dial)
. Accept : Menerima jawaban (percakapan)
jawab dari siapa
(introduction)
. Read & Write : Percakapan sesungguhnya
. Close : Akhiri (tutup telepon)

Kesimpulannya TCP bersifat connection-oriented, full-duplex, byte stream service


, dan
reliable.

TCP dan UDP menggunakan 16-bit numbers.


Semuanya terbagi dalam 3 tipe:
1. Well-known Ports : 0-1023 ( dikontrol oleh IANA )
2. Registered Ports : 1024-49159
3. Ephemeral / Dynamic Ports : 49152-65535
( berdasarkan pada RFC )

IANA
Internet Assigned Numbers Authority adalah lembaga yang berwewenang
untuk mengatur angka untuk berberapa protokol yang ada.

1.3. ARPANET

ARPANET merupakan jaringan experimental yang diciptakan dan dikembangkan oleh


DARPA (Defense Advance Research Project Agency) pada tahun 1969.

Populer pada tahun 1975 sehingga pada akhirnya terciptalah pemrograman berbasis
TCP/IP yang awalnya hanya terdapat pada MILNET (Military Network) dan berkembang
menjadi INTERNET.

Aktivitas yang ada diatur dalam RFC (Internet Request For Comments).

1.4. OSI 7 Layer

Pada OSI 7 Layer, program client-server bergerak menggunakan Internet Protocol (


IPv4
atau IPv6) melalui lapisan data link ( layer 2 ).
7. Application
6. Presentation
5. Session
4. Transport
3. Network
2. Data Link
1. Physical

Jika ada 2 program dengan layering seperti di atas maka jalannya program adalah:
7c <-> 6c <-> 5c <-> 4c <-> 3c <-> 2c <-> 1c ..
. <-> 1s <-> 2s

Dengan :
c = client
s = server

<-> 7s

1.5. TCP/IP Layer

Pada layer TCP/IP, koneksi TCP dan UDP terdapat pada ( layer 3 ).
4. Application (DHCP, DNS, FTP, HTTP, IMAP,
IRC, POP, RTP, SMTP, SNMP, SSH, Telnet,
SSL, SOCKS)
3. Transport (TCP, UDP, RSVP)
2. Internet (IP [IPv4,IPv6], ICMP(ICMP, ICMPv6)
1. Physical/Link Layer (ARP, NDP, OSPF, PPP,
MAC (Ethernet, DSL, ISDN)

1.6. Pemrograman Network Programming

Network programming dapat dilakukan pada berbagai macam operating system (OS) /
sistem operasi. Sistem operasi yang umum dilakukan adalah :
1. Windows
2. Linux

Pada sistem operasi Windows, metode yang dapat dilakukan adalah menggunakan
metode:
1. RPC (Windows NT Remote Procedure Call)
2. WinSock (Windows Socket)
3. WinNet API (File Server
Printer)

Pada sistem operasi Linux dan UNIX, metode yang dapat dilakukan adalah menggunak
an
metode pemanggilan sistem melalui socket(); yang terdapat pada #include
<sys/socket.h>

Pemrograman pada network programming non-windows, juga memiliki beberapa kode


families khusus (Address Families).

Berikut ini adalah Address Familiesnya:

.
.
.
.
.

Unix / Linux Domain: AF_UNIX


TCP/IPv4 Domain: AF_INET
TCP/IPv6 Domain: AF_INET6
Novell NetWare Domain: AF_IPX
AppleTalk Domain: AF_APPLETALK

Selain itu, juga terdapat protocol families yang mengaturnya, diantaranya:


.
.
.
.
.

Unix / Linux Domain: PF_UNIX


TCP/IPv4 Domain: PF_INET
TCP/IPv6 Domain: PF_INET6
Novell NetWare Domain: PF_IPX
AppleTalk Domain: PF_APPLETALK

1.7. Winsock Programming

Pemrograman Network (Network Programming) menggunakan Windows (WINSOCK),


menggunakan WSA.

WSA merupakan singkatan dari Windows Socket API.

Salah satu fitur fungsi yang terdapat pada library WSA yang memiliki kapabilitas
pemrograman jaringan yaitu inisiasi adalah WSAStartup() .

Sedangkan untuk data-datanya digunakan WSAData (bertipe struct)

Pastikan setelah menggunakan WSAStartup(), program dapat menterminate/mengakhiri


socket yang ada dengan menggunakan WSACleanup().

1.8. I/O Model

Pada pemrograman berbasis networking (network programming) adalah mungkin


untuk terjadinya akses secara bersamaan (concurrent) dan dengan jumlah banyak. U
ntuk
mengantisipasi masalah yang dapat ditimbulkan oleh akses bersamaan tersebut maka
aplikasi membutuhkan pengantisipasian. Terutama untuk permasalahan pengaturan I/
O
deskriptor pada saat yang bersamaan diakses (contohnya: file, socket deskriptor,
dan
multiple socket deskriptor).

I/O Multiplexing merupakan bagian dari I/O Model, dimana I/O model tersebut diba
gi
menjadi 5 bagian:
1. Blocking I/O
2. Non-Blocking I/O

3. I/O Multiplexing
select()
4. Signal Driven I/O
5. Asynchronous I/O

Question (must know dude, if you wanna goal master it !!) :


1. What is data encapsulation?
2. What is socket?
3. Can windows operating system run socket?
4. What is IP-RFC?
5. 2001:0db8:c9d2:aee5:73e3:934a:a5ae:9551 is Ipv4 or Ipv6?
6. Remember subnet? Tell me the range!
7. What is struct?
8. Open this site : The IANA Port List, find out. .
9. Tell me socket step, this last one easy, read above once more if forgot [syst
em clientsocket], but please master it!! .

To compile any of program in this HOL use:


gcc <name of source>

o <name of executeable>

To compile any of program in this HOL use (if contain thread) :


gcc <name of source> o <name of executeable> -lpthread

GCC = GNU C Compiler


o = output

Chapter 02
Introduction to I/O Multiplexing and Non
Blocking System

Objective:
.
.
.
.
.
.
.

I/O Multiplexing
Non Blocking System
Bzero memory Operations
Memcpy dan Memset
Little Endian (LSB) dan Big Endian (MSB)
gethostname, gethostbyname and inet_ntoa
Sockaddr

Learning Outcome:
. Memilih teknik dan protocol pemrogram jaringan untuk pemecahan suatu masalah
. Memperhitungkan beberapa program dengan protokol yang umum dipergunakan pada
jaringan komputer.
. Menjelaskan berbagai macam komponen yang berhubungan dengan pemrograman
jaringan

2.1 I/O Multiplexing

select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO


for synchronous I/O multiplexing
References : Linux Manual
/* According to POSIX.1-2001 */
#include <sys/select.h>

/* According to earlier standards */


#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

//select according to earlier standard


int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

void FD_CLR(int fd, fd_set *set);


int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

#define _XOPEN_SOURCE 600


#include <sys/select.h>

//pselect according to earlier standard


int pselect(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask);

2.2 Non Blocking System

Pada dasarnya sistem default dari suatu socket adalah blocking system.
Artinya pemanggilan socket tidak dapat dilakukan secara langsung melainkan harus
melalui proses sleep dan menunggu suatu kondisi untuk menjadi true.

Ada 4 kategori dalam socket call:


1.
2.
3.
4.

Input Operations
Output Operations
Accepting Incoming connections
Initiate outgoing connection

Input operations sendiri dibagi atas 5 fungsi dasar diantaranya : read, readv, r
ecv,
recvfrom dan recvmsg.

Output operations juga dibagi atas 5 fungsi dasar diantaranya : write, writev, s
end,
sendto, dan sendmsg.

Untuk Accepting incoming connection dapat menggunakan fungsi accept.

Sedangkan, Initiating outgoing connections menggunakan fungsi connect.

Lalu bagaimana caranya melakukan Non Blocking System?


Non Blocking System dapat dilakukan dengan mengunakan str_cli (googling lah
source-code ini)-Ubitoquous.

Fungsi yang dipakai non-blocking system I/O adalah fungsi select. Fungsi ini dip
akai
untuk menentukan kondisi dimana deskriptor sedang readable atau writeable.

Untuk menunjukan kinerja client server pada komputer yang sama adapat menggunaka
n
fungsi fork.

Untuk sistem yang lebih canggih (TCP threeway-handshake), dapat menggunakan


nonblocking connect. Hal tersebut tidak dibahas dalam buku ini tapi Anda dapat t
emukan
dengan mudah di internet.

2.3 Bzero memory operations

Fungsi Bzero adalah menuliskan sejumlah null bytes ke tujuan. Jika bzero(char *d
est, int
nbytes) diisi dengan bzero(nama,10) maka nama akan dimasukan sejumlah 10 null by
tes.

Untuk lebih mengerti silakan compile source code berikut:


#include <stdio.h>
#include <string.h>

int main()
{
//Baris ini untuk mendeklarasikan variabel pendukung
int i, len;

//baris untuk mencoba bzero (boleh diganti) [i]


int ID[] = { 1, 1, 2, 3, 1, 2, 3, 4, 5, 6 };
char name[] = { "Successor Learner" };

printf("BZero Course\n");
printf("=-=-=-=-=-=-\n\n");

//mencetak ID sebelum di bzero


printf("\"ID\" before bzero proceeded : ");

//ukur panjang per panjang data type


//<-- jika baris di atas [i] diganti tipe data,
//maka yang baris ini juga diganti
len = sizeof(ID)/sizeof(int);
for (i = 0; i<len; i++)
printf ("%d", ID[i]);

//proceed bzero at ID
bzero (ID,sizeof(int)*3);
printf("\n\"ID\" after bzero (ID,sizeof(int)*3) : ");
for (i = 0; i<len; i++)
printf ("%d", ID[i]);

//mencetak name sebelum di bzero


printf("\n\n\"Name\" before bzero proceeded : ");

//ukur panjang per panjang data type


//<-- jika baris di atas [i] diganti tipe data,
//maka yang baris ini juga diganti
len = strlen(name);
for(i=0; i<len; i++)
printf("%c",name[i]);

//proceed bzero at Name

bzero(name,sizeof(char)*3);
printf("\n\"Name\" after bzero(name,sizeof(char)*3) : ");
for(i=0; i<len; i++)
printf("%c", name[i]);

return 0;
}

Output:
"ID" before bzero proceeded : 1123123456
"ID" after bzero (ID,sizeof(int)*3): 0003123456
"Name" before bzero proceeded : Successor Learner
"Name" after bzero(name,sizeof(char)*3) : cessor Learner

2.4 Memcpy dan Memset

Memcpy adalah mencopy/menyalin sejumlah byte dari lokasi penujukan asal ( source
) ke
memori yang ditunjuk/dituju ( destination ).
char exampleword1[]="Sample string";
char exampleword2[50];
char exampleword3[50];

memcpy (exampleword2,exampleword1,strlen(exampleword3)+1);
memcpy (exampleword3,"copy completed!",16);
printf ("Example Word1: %s\n",str1);
printf ("Example Word2: %s\n",str2);
printf ("Example Word3: %s\n",str3);
maka tercetak
Example Word1: Sample string
Example Word2: Sample string
Example Word3: copy completed!
Memset adalah mengisi block dari memori.
Contoh:
char words[25] = " love you Sky =P";
memset (words,'I',3);
puts (words);
maka tercetak
"III love you Sky =P
Pertanyaannya: Apa perbedaan antara memcpy dan strcpy?
Untuk lebih mengerti silakan compile source code berikut:
#include <stdio.h>
#include <string.h>

int main()
{
//Baris ini untuk mendeklarasikan variabel pendukung
int i, len;

//baris untuk mencoba memcpy dan memset (boleh diganti) [i]


int ID[] = { 1, 1, 0, 0, 1, 2, 3, 4, 5, 6 };
char name1[] = { "Successor Learner" };
char name2[69]="";

printf("Memset and Memcopy Course\n");


printf("=-=-=-=-=-=-\n\n");

//mencetak isi name1 sebelum memcpy


printf("Content of \"name1\" : %s", name1);

//melakukan memcpy
memcpy (name2,name1,sizeof(name1));

//mencetak hasil memcpy


printf("\n\"name2\" result of memcpy(name2,name1,sizeof(name1)) :
\n%s\n", name2);

//mencetak isi id sebelum memset


printf("\n\"ID\" before memset : ");
len = sizeof(ID)/sizeof(int);
for(i=0; i<len; i++)

printf("%d",ID[i]);

//melakukan memset
memset (ID,0,sizeof(int)*3);

printf("\n\"ID\" after memset (ID,0,sizeof(int)*3) : ");


for(i=0; i<len; i++)
printf("%d",ID[i]);

printf("\n");
return 0;
}

2.5 Little Endian (LSB) dan Big Endian (MSB)

Konsep Little Endian dan Big Endian erat kaitannya dengan memori. Oleh sebab itu
, untuk
dapat mengerti kedua hal tersebut diperlukan pengetahuan dasar mengenai memori.

Sederhananya, memori adalah sederet array berukuran besar dengan setiap arraynya
mengandung bytes. Hanya saja dalam dunia komputer di bidang memori yang dikenal
bukanlah index melainkan istilah address . Itulah sebabnya memori terkadang dike
nal
dengan istilah byte-addressable.

Berikut ini adalah gambaran mudah mengenai Little Endian dan Big Endian.
Big Endian
Address
1009
1010
1011
1012

Value
A
B
C
D

Dari tabel ini didapatkan kesimpulan bahwa pada Big Endian, kita menyimpan the M
ost
Significant Byte pada address terkecil.

Little Endian

Address
1009
1010
1011
1012
Value
D
C
B
A

Dari tabel ini didapatkan kesimpulan bahwa pada Little Endian, kita menyimpan th
e Least
Significant Byte (LSB) pada address terkecil.
Conclusion = LSB reverse of MSB
Jika masih tidak mengerti, compilelah code di bawah ini:
Note: Pada buku ini, Little endian dan Big endian adalah konsep, bukan fungsi!!

#include <stdio.h>

union data
{
short s;
char c[sizeof(short)];
}uni;

int main()
{
uni.s = 0x0207;

printf("Address uni.s = %d\n", &uni.s);


printf("Address uni.c[0]= %d\n", &uni.c[0]);
printf("Address uni.c[1]= %d\n\n", &uni.c[1]);

printf("Value c[0] = %d\n", uni.c[0]);


printf("Value c[1] = %d\n", uni.c[1]);

//pahami cara membaca memori, dan perhatikanlah uni.s


//Anda akan mengerti =)
if(uni.c[1]==7 && uni.c[0]==2)
printf("\nBig endian");
else if(uni.c[0]==7 && uni.c[1]==2)
printf("\nLittle endian");
else
printf("\n...");

printf("\n");
return 0;

2.6 gethostname, gethostbyname and inet_ntoa

gethostname adalah fungsi untuk mengembalikan nilai hostname dari komputer saat
ini
(return the name of the system)
int gethostname(char *name, size_t namelen);
.
.
.
.

name diisi dengan variabel penampung nama


namelen diisi dengan panjang tampungan nama (sizeof)
return -1 jika error
return 0 jika success
warning: gethostbyname already deprecated when this HOL created!!

struct hostent *gethostbyname(const char *name);


. name diisi dengan variabel penampung nama
. return struct hostent

Adapun isi dari struct hostent:


char *h_name : Nama asli dari hostname
char **h_aliases : List alias.
int h_addrtype : Address type (AF_INET type)
int length : panjang alamat dalam bytes
char **h_addr_list : list IP address
h_addr : alias dari h_addr_list[0]

compile dan pelajari!!!

Deprecated? Ya, dan inilah yang baru!!

struct hostent *gethostbyaddr(const char *addr, int len, int type);

returnnya sama.
Tapi lebih siap menghadapi Ipv6, temukan mengapa? .

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

//Semuanya deprecated!!
//Use inet_pton() or inet_ntop() instead!!

char *inet_ntoa(struct in_addr in);


int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
Ingat, semuanya sudah deprecated, tapi penulis rasa tetap perlu untuk menyajikan
nya,
sebab ini adalah dasarnya
char *inet_ntoa(struct in_addr in);

. input berupa struct in_addr, untuk memahami perhatikan prototype struct


dibawah.
. return dot type IP (misalnya : 10.22.69.69)
o n for network
o a for ascii
o so ntoa berarti network to ascii,
. Question: ascii to network?
. Clue: return int (must try by yourself) .

Pelajari prototype struct di bawah ini, karena inilah dasar Network Programming
!!!
include <netinet/in.h>

// All pointers to socket address structures are often cast to pointers


// to this type before use in various functions and system calls:

struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};

// IPv4 AF_INET sockets:

struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};

struct in_addr {
unsigned long s_addr; // load with inet_pton()
};

// IPv6 AF_INET6 sockets:

struct sockaddr_in6 {

u_int16_t sin6_family; // address family, AF_INET6


u_int16_t sin6_port; // port number, Network Byte Order
u_int32_t sin6_flowinfo; // IPv6 flow information
struct in6_addr sin6_addr; // IPv6 address
u_int32_t sin6_scope_id; // Scope ID
};

struct in6_addr {
unsigned char s6_addr[16]; // load with inet_pton()
};

// General socket address holding structure, big enough to hold either


// struct sockaddr_in or struct sockaddr_in6 data:

struct sockaddr_storage {
sa_family_t ss_family; // address family

// all this is padding, implementation specific, ignore it:


char __ss_pad1[_SS_PAD1SIZE];
int64_t __ss_align;
char __ss_pad2[_SS_PAD2SIZE];
};

Jika masih tidak mengerti, compilelah source code dibawah ini:


#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>

int main()
{
struct hostent *host;
char compName[20];
char* compIp;

//applying gethostname
int hostname = gethostname(compName,sizeof(compName));

printf("Course about : gethostname, gethostbyname, dan inet_ntoa


\n\n");

//jika hostname mengembalikan -1 maka gethostname gagal.


if(hostname == -1){
printf("gethostname Failed!, Press ENTER to terminate!!\n");
getchar();
return 1;
}
else if(hostname==0)
printf("Computer Name : %s\n",compName);

host = gethostbyname(compName);

//jika host kosong atau NULL, maka gethostname gagal!!


if( ! host){
printf("gethostbyname Failed!, Press ENTER to terminate!!\n");
getchar();
return 1;
}
else
{
//mengimplementasi iet_ntoa (diubah ke IP address diambil dari
isi host)
compIp = inet_ntoa(*((struct in_addr*)host->h_addr));
printf("IP of Computer : %s\n",compIp);
}
return 0;
}

2.7 Sockaddr

Adalah struct yang menampung informasi alamat socket untuk banyak tipe dari
sockets.
Contoh: Sudah di jelaskan di atas, ingat? .

Jika masih tidak mengerti, compilelah source code dibawah ini:


#include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main()
{
char *ip1, *ip2;
struct sockaddr_in host1,host2;

//masukan ip address, coba dan anda mengerti


host1.sin_addr.s_addr = inet_addr("10.22.69.69");
host2.sin_addr.s_addr = inet_addr("10.22.96.96");

//ingat ntoa artinya apa?


//jika tidak ingat, baca penjelasan sebelumnya
//saya tidak mengulang 2x :P
ip1 = inet_ntoa(host1.sin_addr);
ip2 = inet_ntoa(host2.sin_addr);

//cetak IP addressnya
printf("\"IP1 Address\": %s\n",ip1);
printf("\"IP2 Address\": %s\n",ip2);

return 0;
}
Code sockaddr
Question
1. Ubahlah statement (code sockaddr):

char *compIp1, *compIp2;


menjadi
char compIp1[50], compIp2[50];
dan
compIp1 = inet_ntoa(host1.sin_addr);
compIp2 = inet_ntoa(host2.sin_addr);
menjadi
strcpy(compIp1,inet_ntoa(host1.sin_addr);
strcpy(compIp2,inet_ntoa(host2.sin_addr);
Apakah outputnya? Mengapa IP keduanya tidak sama?
2.
3.
4.
5.

Apa
Apa
Apa
Apa

itu
itu
itu
itu

sa_family? Jelaskan!
sin_addr? Jelaskan!
program client-server?
bzero?

Chapter 03
Program Client - Server

Objective:
.
.
.
.
.

Definisi Program Client Server


Program Client - Server dasar
Program Client - Server with Thread
Setsockopt dan sigaction
Question

Learning Outcome:
. Memilih teknik dan protocol pemrogram jaringan untuk pemecahan suatu masalah
. Memperhitungkan beberapa program dengan protokol yang umum dipergunakan pada
jaringan komputer.
. Menjelaskan berbagai macam komponen yang berhubungan dengan pemrograman jaring
an

3.1. Definisi Program Client-Server

(Seperti pengertian pada Chapter 1) Program client-server adalah suatu program y


ang
terdiri dari client dan server. Server disini bekerja sebagai penyedia resources
, sedangkan
client adalah pihak yang merequest/meminta resources.
3.2. Program Client

Server Dasar

Pada bagian ini akan dikemukakan code beserta dengan penjelasannya. Code Lover,
bagian ini akan mempermudah Anda mempelajarinya. Setiap bagian code akan diberik
an
comment dan penjelasan dasar yang mengarahkan Anda untuk mengerti.
3.2.1. Program Server

Dalam program server yang umumnya ada adalah:


1.
2.
3.
4.
5.
6.

Socket
Bind
Listen
Accept
Read & Write
Close

Penjelasannya dirangkum dalam code dibawah ini:


Compilelah dan baca comment di bawah ini:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <strings.h>

//argc = jumlah parameter


//args = parameter yang dikirim dari command prompt/command

line/run

int main(int argc, char**args)


{
int sockfd, newsockfd, noport, client_size;
char message[255], fflush;
struct sockaddr_in server,client;

//parameter 1 = application name


//parameter 2 = sending parameter
//length should be 2
if(argc!=2)
{
printf("Insufficient Parameter!!!\n");
return 0;

//passing port to noport


//atoi adalah ascii to integer
noport = atoi(args[1]);

//get the file descriptor


//socket adalah system call di UNIX
//int socket(int domain, int type, int protocol);
//domain:
// AF_UNIX (former) atau AF_INET (later)
//type:
// SOCK_STREAM atau SOCK_DGRAM
//protocol:
//0 = UDP or TCP will be controlled by system.
sockfd = socket(AF_INET,SOCK_STREAM,0);

//return -1 if error
if(sockfd == -1)
{
perror ("Error : Socket Failed!, Get File Descriptor
Error!! : \n");
return 1;
}

//sets all values in a buffer to zero


bzero(&server,sizeof(server));

//set address family (biasanya simbolik : AF_INET)


server.sin_family = AF_INET;

//set port number


//htons digunakan untuk mengkonversi
//port number dalam host byte
//ke port number dalam network byte order
server.sin_port = htons(noport);

//memasukan server addres


//INADDR_ANY untuk menujuk IP server dimana server running
server.sin_addr.s_addr = INADDR_ANY;

printf("Server Have Been Activated\n");

//aktivasi menyatakan di port mana saya aktif


//pada game jaringan seperti Counter-Strike dan sejenisnya
//inilah yang memberitahukan "connect to 192.168.5.10 port
1120"
//Bind server to port
//Jika langsung listen(), lupakan baris ini
if(bind(sockfd,(struct sockaddr*)&server,sizeof(server)) ==
-1)
{
perror("Error: Bind to port Failed!\n");
return 1;
}

//Bagian menunggu panggilan dari client, listetening

//listen(sockfd, backlog)
//backlog = jumlah maksimal client connect
//biasanya maksimal 20
//tapi cenderung dipilih 5 atau 10
if(listen(sockfd,5) == -1)
{
perror("Error: Listen Failed!");
return 1;
}

printf ("Waiting for connection ...\n");

//get clientsize
client_size = sizeof(client);

//"Thank you for calling port 3490."


//That what accept used for
//read chapter 1 carefully and you will
//understand
newsockfd = accept(sockfd,(struct
sockaddr*)&client,(socklen_t*)&client_size);

//int accept(int sockfd, struct sockaddr *addr, socklen_t


*addrlen);
//return -1 if error
if(newsockfd == -1)
{
perror("Error : Accept Error!\n");
return 1;
}

int nMsg = 0;
do {
//set all buffer message to zero
bzero(message,sizeof(message));

//You can!" The longer answer is,


//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read
and write
if(read(newsockfd,message,sizeof(message)) == -1)
{
perror("Error: Read failed! \n");
return 1;
}

printf("\nMessage : %s\n",message);

if(strcmp (message, "exit") != 0)


{
printf("Number of Message: %d.\n", nMsg + 1);
printf("Message Length : %d character.\n",
strlen(message));
nMsg++;
}

} while (strcmp (message, "exit") != 0);

printf("Sent 'thank you' message to client!\n");

//clean buffer of bzero


//clear all.
bzero(message,sizeof(message));

//copy thank you message to message


strcpy (message, "thank you");

//sending message via socket descriptor


if(write(newsockfd,message,sizeof(message)) == -1)
{
perror("Error : Write failed!\n");
return 1;
}

//close newsocketdf (accept)


close(newsockfd);
//close sockedf (socket)
close(sockfd);
return 0;
}
3.2.2. Program Client

Dalam program client yang umumnya ada adalah:


1. Socket
2. Connect

3. Read & Write


4. Close
Penjelasannya dirangkum dalam code dibawah ini:
Compilelah dan baca comment di bawah ini:
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<strings.h>

//argc = jumlah parameter


//args = parameter yang dikirim dari command prompt/command
line/run
int main(int argc, char**args)
{
int sockfd,noport;
char message[255],fflush;
struct sockaddr_in server;
struct hostent * host_server;

//parameter 1 = application name


//parameter 2 = server IP
//parameter 3 = port
//length should be 3
if(argc!=3)
{
printf("Insufficient Parameter!!!\\n");
return 0;
}

//passing port to noport


//atoi adalah ascii to integer
noport = atoi(args[2]);

//get host of server


host_server = gethostbyname(args[1]);

//get the file descriptor


//socket adalah system call di UNIX
//int socket(int domain, int type, int protocol);
//domain:
// AF_UNIX (former) atau AF_INET (later)
//type:
// SOCK_STREAM atau SOCK_DGRAM
//protocol:
//0 = UDP or TCP will be controlled by system.
sockfd = socket(AF_INET,SOCK_STREAM,0);

//return -1 if error

if(sockfd == -1)
{
perror ("Error : Socket Failed!, Get File
Descriptor Error!! : \n");
return 1;
}

//sets all values in a buffer to zero


bzero(&server,sizeof(server));

//set address family (biasanya simbolik : AF_INET)


server.sin_family = AF_INET;

//set port number


//htons digunakan untuk mengkonversi
//port number dalam host byte
//ke port number dalam network byte order
server.sin_port = htons(noport);

//copy address of server with length


//read chapter 2 for further info
memcpy(&host_server>h_addr,&server.sin_addr.s_addr,host_server->h_length);

//perform connect to server


if(connect(sockfd,(struct
sockaddr*)&server,sizeof(server)) == -1)

{
perror("Error: Connect Error!\n");
return 1;
}

printf("Client Active!\n");
do {
//set all buffer message to zero
bzero(message,sizeof(message));
do
{
printf("Input message [1..50 char]: ");
scanf("%[^\n]",message);
scanf("%c",&fflush);
//simple validation
}while(strlen(message)<1 ||
strlen(message)>50);

//sending message via socket descriptor


if(write(sockfd,message,sizeof(message)) == -1)
{
perror("Error : Write failed!\n");
return 1;
}
} while (strcmp (message, "exit") != 0);

//set all buffer message to zero


bzero(message,sizeof(message));

//You can!" The longer answer is,

//"You can, but send() and recv() offer


//much greater control over your data transmission.
//Because it using file descriptor, so it can read
and write
if(read(sockfd,message,sizeof(message)) == -1)
{
perror("Error: Read failed! \n");
return 1;
}

//cetak message dari server


printf("\Message from server : %s\n",message);

//close sockfd
close(sockfd);

return 0;
}

3.3. Program Client

Server with Thread

Pada bagian ini akan dikemukakan code beserta dengan penjelasannya. Code Lover,
bagian ini akan mempermudah Anda mempelajarinya. Setiap bagian code akan diberik
an
comment dan penjelasan dasar yang mengarahkan Anda untuk mengerti. Yang
membedakan adalah, disediakan thread, dimana thread memungkinkan
memungkinkan sebuah program untuk membagi dirinya menjadi beberapa task yang bis
a
berjalan bersamaan sekaligus. Task
task ini mempunyai Process ID (PID) yang sama
.
3.3.1. Program Server with thread

Merupakan program server (sebelumnya) yang ditambahkan dengan thread.


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

//thread proc (procedure doesn't return data type)


void *thread_proc(void *arg)
{
char message[255],fflush;
int nMessage = 0;

int sockfd;
//input argument for sockfd
sockfd = (int) arg;

printf("\nClient with (FD %d) come in!\n",sockfd);

do {
//set all buffer message to zero
bzero(message,sizeof(message));

//You can!" The longer answer is,


//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read
and write

if(read(sockfd,message,sizeof(message)) == -1)
{
perror("Error: Read failed! \n");
return 1;
}
printf("\nMessage from client (FD %d) :
%s\n",arg,message);

if(strcmp (message, "exit") != 0)

{
printf("This is message no. : %d.\n", nMessage
+ 1);
printf("Message Length : %d character.\n",
strlen(message));
nMessage++;
}
} while (strcmp (message, "exit") != 0);

printf("Sent Thank You message to client (FD %d)\n",arg);

//set all buffer message to zero


bzero(message,sizeof(message));

strcpy (message, "Thank You");

//sending message via socket descriptor


if(write(sockfd,message,sizeof(message))==-1)
{
perror("Error : Write failed!\n");
return 1;
}
printf("Client (FD %d) disconnected\n",arg);

//close socket
close(sockfd);
}

int main(int argc, char**args)


{
int sockfd, noport, newsockfd;

int client_size, opval=1;


struct sockaddr_in serv,cli;

//thread id
pthread_t thread_id;

//parameter 1 = application name


//parameter 2 = port
//length should be 2

if(argc!=2)
{
printf("Insufficient Parameter!!!\\n");
return 0;
}

//passing port to noport


//atoi adalah ascii to integer
noport = atoi(args[1]);

//get the file descriptor


//socket adalah system call di UNIX
//int socket(int domain, int type, int protocol);
//domain:
// AF_UNIX (former) atau AF_INET (later)
//type:

// SOCK_STREAM atau SOCK_DGRAM


//protocol:
//0 = UDP or TCP will be controlled by system.
sockfd = socket(AF_INET,SOCK_STREAM,0);

//return -1 if error
if(sockfd == -1)
{
perror ("Error : Socket Failed!, Get File Descriptor
Error!! : \n");
return 1;
}

//membook socket yang sudah di buat


//sehingga port yang sudah dipakai tidak
//dapat di bind kembali
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opval,sizeof(
opval)) == -1)
{
perror("Error : Socket Option Error!!\n");
return 1;
}

//set all buffer message to zero


bzero(&serv,sizeof(serv));

//set address family (biasanya simbolik : AF_INET)


serv.sin_family = AF_INET;

//set port number


//htons digunakan untuk mengkonversi

//port number dalam host byte


//ke port number dalam network byte order
serv.sin_port = htons(noport);

//memasukan server addres


//INADDR_ANY untuk menujuk IP server dimana server running
serv.sin_addr.s_addr = INADDR_ANY;

//aktivasi menyatakan di port mana saya aktif


//pada game jaringan seperti Counter-Strike dan sejenisnya
//inilah yang memberitahukan "connect to 192.168.5.10 port
1120"
//Bind server to port
//Jika langsung listen(), lupakan baris ini
if(bind(sockfd,(struct sockaddr*)&serv, sizeof(serv)) == 1)
{
perror("Error: Bind to port Failed!\n");
return 1;
}

//Bagian menunggu panggilan dari client, listetening


//listen(sockfd, backlog)
//backlog = jumlah maksimal client connect
//biasanya maksimal 20
//tapi cenderung dipilih 5 atau 10

if(listen(sockfd,5) == -1)
{
perror("Error: Listen Failed!");
return 1;
}

printf("Server Active!\n");
while(true) //loop forever
{
//save client size
client_size = sizeof(cli);

//"Thank you for calling port 3490."


//That what accept used for
//read chapter 1 carefully and you will
//understand
newsockfd = accept(sockfd,(struct
sockaddr*)&cli,(socklen_t*)&cli);

//int accept(int sockfd, struct sockaddr *addr,


socklen_t *addrlen);
//return -1 if error
if(newsockfd == -1)
{
perror("Error : Accept Error!\n");
return 1;
}

//create thread
if(pthread_create(&thread_id,NULL,thread_proc,(void*)newsockfd) == -1)

{
perror("Error : Create Thread Error\n");
return 1;
}

//detach thread
pthread_detach(thread_id);
}

//close socket
close(sockfd);

return 0;
}

3.3.2. Program Client with thread

Merupakan program client (sebelumnya) yang ditambahkan dengan thread.


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

int main(int argc, char**args)


{
struct sockaddr_in serv;
struct hostent *host;

int sockfd, noport, i;


char message[255],fflush;

//parameter 1 = application name


//parameter 2 = server IP
//parameter 3 = port
//length should be 3
if(argc!=3)
{
printf("Insufficient Parameter!!!\\n");
return 0;

//passing port to noport


//atoi adalah ascii to integer
noport = atoi(args[2]);

//get the file descriptor


//socket adalah system call di UNIX
//int socket(int domain, int type, int protocol);
//domain:
// AF_UNIX (former) atau AF_INET (later)
//type:
// SOCK_STREAM atau SOCK_DGRAM
//protocol:
//0 = UDP or TCP will be controlled by system.
sockfd = socket(AF_INET,SOCK_STREAM,0);

//return -1 if error
if(sockfd == -1)
{
perror ("Error : Socket Failed!, Get File Descriptor
Error!! : \n");
return -1;
}

//set all buffer message to zero


bzero(&serv,sizeof(serv));

//set address family (biasanya simbolik : AF_INET)


serv.sin_family = AF_INET;

//set port number


//htons digunakan untuk mengkonversi
//port number dalam host byte
//ke port number dalam network byte order
serv.sin_port = htons(noport);

//memasukan server addres


serv.sin_addr.s_addr = inet_addr(args[1]);

//perform connect to server


if(connect(sockfd,(struct sockaddr*)&serv,sizeof(serv)) ==
-1)
{
perror("Error: Connect Error!\n");
return 1;
}

printf("Client Active!\n");
do {
//set all buffer message to zero
bzero(message,sizeof(message));
do
{
printf("Input message [1..50 char]: ");
scanf("%[^\n]",message);
scanf("%c",&fflush);
//simple validation

}while(strlen(message)<1 || strlen(message)>50);

//sending message via socket descriptor


if(write(sockfd,message,sizeof(message)) == -1)
{
perror("Error : Write failed!\n");
return 1;
}
} while (strcmp (message, "exit") != 0);

//set all buffer message to zero


bzero(message,sizeof(message));

//You can!" The longer answer is,


//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read and
write
if(read(sockfd,message,sizeof(message)) == -1)
{
perror("Error: Read failed! \n");
return 1;
}

printf("\nMessage from server server : %s\n",message);

//close socket

close (sockfd);
return 0;
}

3.4. Setsockopt dan sigaction

Setsockopt digunakan untuk mengeset/memanipulasi opsi (option) dari socket.


Contohnya agar suatu address yang sudah di bind boleh dipakai lagi.
Sigaction digunakan untuk mengubah aksi yang digunakan program atas signal yang
diterima. Sigaction dapat mengatur handler dan penanganan signal-signal yang tel
ah
terdaftar dalam struktur data sigaction.

3.5. Question
1. What is thread used for?
2. What is setsockopt and sigaction?
3. What should appear in socket for client and server?
To compile any of program in this HOL use:
gcc <name of source>

o <name of executeable>

To compile any of program in this HOL use (if contain thread) :


gcc <name of source> o <name of executeable> -lpthread
GCC = GNU C Compiler
o = output

Chapter 04
Advance Program Client - Server

Objective:
.
.
.
.
.
.
.

Select
FD_Set
FD_Zero
FD_ISSET
FD_CLR
Example of Select with input trigger
Example select implemented in client server

Learning Outcome:
. Memilih teknik dan protocol pemrogram jaringan untuk pemecahan suatu masalah
. Memperhitungkan beberapa program dengan protokol yang umum dipergunakan pada
jaringan komputer.
. Menjelaskan berbagai macam komponen yang berhubungan dengan pemrograman jaring
an

4.1. Select

Pada pemrograman standard network programming terdapat fungsi accept(), yang


menunggu request dan melakukan fork untuk membagi proses menjadi dua dan proses
child akan menghandle koneksi yang ada dan server utama tetap dapat menunggu req
uest
yang datang.
Select() disini berguna untuk menghadapi 1 proses yang bersifat multiplex untuk
semua
request (artinya membuatnya dapat menerima request semaksimal mungkin)
Jadi, mengapa menggunakan select()?
Keuntungan menggunakan select() yaitu server hanya membutuhkan 1 proses saja unt
uk
menghandle semua request (tanpa perlu fork() ing).

4.2. FD_SET

Select() pada penjelasan diatas bekerja ketika ada perubahan pada file descripto
r (socket).
Caranya adalah mengisi fd_set dengan macro.
Fungsi terdapat pada : #include <sys/select.h>
Terdiri dari 2 parameter :
FD_SET(int fd, fd_set *fdset);

Jadi FD_SET adalah fungsi yang berguna untuk menetapkan nilai bit untuk file des
criptor
(fd) dalam file deskriptor yang diletakan dalam fd_set.
Note:
FD_SET (0, &fdread);
Jika terdapat nilai fd = 0, maka yang dimaksud adalah masukan berupa standard in
put.

4.3. FD_ZERO

FD_ZERO digunakan untuk menetapkan fdset yang ada untuk memiliki zero bit untuk

semua file descriptors (untuk membersihkan isi variabel fdread).


Fungsi terdapat pada : #include <sys/select.h>
Terdiri dari 1 parameter :
FD_ZERO(&fdset)

4.4. FD_ISSET

FD_ISSET digunakan untuk melakukan pengecekan non-zero value. Jika file


mengandung bit non-zero terdapat pada pada lokasi yang ditunjuk fdset dan 0 (and
otherwise).
Fungsi terdapat pada : #include <sys/select.h>
Terdiri dari 2 parameter :
FD_ISSET(fd, &fdset)
Note:
FD_ ISSET (0, &fdread);
Jika terdapat nilai fd = 0, maka yang dimaksud adalah masukan berupa standard in
put.

4.5. FD_CLR

FD_CLR digunakan untuk menbersikan semua bit pada file deskriptor (fd) dalam fds
et.
Fungsi terdapat pada : #include <sys/select.h>
Terdiri dari 2 parameter :
FD_CLR(fd, &fdset)
Note:
FD_ CLR (0, &fdread);
Jika terdapat nilai fd = 0, maka yang dimaksud adalah masukan berupa standard in
put.

4.6. Example of Select with input trigger

Setelah mempelajari code di atas mungkin akan timbul pertanyaan apakah ada
contohnya? Berikut ini adalah contoh yang bisa dipakai untuk lebih memahami sele

ct.
Compile dan pelajarilah code berikut!
#include<stdio.h>
#include<sys/types.h>
#include<sys/time.h>
#include<unistd.h>

int main()
{
fd_set fdread;

//struct of time
struct timeval time;

FD_ZERO(&fdread);
FD_SET(0,&fdread);

printf("Input interval of second :");


scanf("%ld",&time.tv_sec);

printf("Input end time : : ");


scanf("%ld",&time.tv_usec);

printf("Press Enter Before Time End !\n");

select(1,&fdread,NULL,NULL,&time);

//check whether time out or not


if(FD_ISSET(0,&fdread))
{
printf("Time out not occured!\n");
}

else {
printf("Time out occured - Enter doesn't pressed\n");
}

FD_CLR(0,&fdread);
return 0;
}

Question:
1. Apa perbedaan jika dilakukan penekanan ENTER dan tanpa penekanan ENTER
(pada code diatas)?
2. Apa fungsi FD_CLR? Bolehkah dihilangkan dari code? Mengertikah Anda dengan
program di atas? Jika ya, jelaskan jalannya program!

4.7. Example select implemented in client server

Berikut ini adalah contoh program menggunakan select pada client server
Just copy, compile, and study!! (CCS!!)

(server.c)
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<strings.h>

//define port to access (use 8080 instead)


#define PORT 8080

int main()
{
//set controller
fd_set fd_set_master,fd_set_curr;

//create socket for server and client


struct sockaddr_in serv, cli;

char message[255];

int i,client_size,byte_to_read,j;
int sockfd,newsockfd;

//set maximum of socket descriptor


int max_sockdesc,opval=1;

//set all bit of server fd_set_master to zero

FD_ZERO(&fd_set_master);

//set all bit of fd_set_current to zero


FD_ZERO(&fd_set_curr);

//create socket
sockfd = socket(AF_INET,SOCK_STREAM,0);

//get the file descriptor


//socket adalah system call di UNIX
//int socket(int domain, int type, int protocol);
//domain:
// AF_UNIX (former) atau AF_INET (later)
//type:
// SOCK_STREAM atau SOCK_DGRAM
//protocol:
//0 = UDP or TCP will be controlled by system.
if(sockfd == -1)
{
perror ("Error : Socket Failed!, Get File Descriptor
Error!! : \n");
return 1;
}

//membook socket yang sudah di buat


//sehingga port yang sudah dipakai tidak

//dapat di bind kembali


if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opval,sizeof(opval)
) == -1)
{
perror("Error : Socket Option Error!!\n");
return 1;
}

//set all buffer message to zero


bzero(&serv,sizeof(serv));

//set address family (biasanya simbolik : AF_INET)


serv.sin_family = AF_INET;

//set port number


//htons digunakan untuk mengkonversi
//port number dalam host byte
//ke port number dalam network byte order
serv.sin_port = htons(PORT);

//memasukan server addres


//INADDR_ANY untuk menujuk IP server dimana server running
serv.sin_addr.s_addr = INADDR_ANY;

//aktivasi menyatakan di port mana saya aktif


//pada game jaringan seperti Counter-Strike dan sejenisnya
//inilah yang memberitahukan "connect to 192.168.5.10 port 1120"
//Bind server to port
//Jika langsung listen(), lupakan baris ini
if(bind(sockfd,(struct sockaddr*)&serv, sizeof(serv)) == -1)

{
perror("Error: Bind to port Failed!\n");
return 1;
}

//Bagian menunggu panggilan dari client, listetening


//listen(sockfd, backlog)
//backlog = jumlah maksimal client connect
//biasanya maksimal 20
//tapi cenderung dipilih 5 atau 10
if(listen(sockfd,5) == -1)
{
perror("Error: Listen Failed!");
return 1;
}

//set socketfd dalam fdset


FD_SET(sockfd,&fd_set_master);

//put max size


max_sockdesc = sockfd;

while(true)
{
//set fd_set_curr base on fd_set_master
fd_set_curr = fd_set_master;

if(select(max_sockdesc + 1,&fd_set_curr,NULL,NULL,NULL)<0)
{
perror("Error: Select Failed\n");
return 1;
}

for(i=0; i<=max_sockdesc; i++)


{
//check the bit whether contain non-zero
if(FD_ISSET(i,&fd_set_curr))
{
if(i==sockfd)
{
client_size = sizeof(cli);
//"Thank you for calling port 3490."
//That what accept used for
//read chapter 1 carefully and you will
//understand

newsockfd = accept(sockfd,(struct
sockaddr*)&cli,(socklen_t*)&client_size);

//int accept(int sockfd, struct sockaddr


*addr, socklen_t *addrlen);
//return -1 if error
if(newsockfd == -1)
{
perror("Error: Accept Failed!\n");
return 1;
}

else
{
//set the socket
FD_SET(newsockfd,&fd_set_master);
if(newsockfd > max_sockdesc)
{
max_sockdesc = newsockfd;
}
printf("Accept connection from
client %s at socket %d\n",inet_ntoa(cli.sin_addr),newsockfd);
}
}
else
{
//You can!" The longer answer is,
//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read and write
byte_to_read = read(i,message,sizeof(message));
if(byte_to_read<=0)
{
if(byte_to_read ==0)
{
perror("Socket %d
disconnected\n",i);

else
{
perror("Error : Read
failed!\n");
return 1; }
close(i);
FD_CLR(i,&fd_set_master);
}
else
{
for(j=0; j<=max_sockdesc; j++)
{
if(FD_ISSET(j,&fd_set_master))
{
if(j!=sockfd && j!=i)
{

//sending message via socket descriptor


if(write(j,message,byte_to_read)<0)
{
perror("Error : Write failed!\n");
return 1;
}
}
}
}
}
}

}
}
}

return 0;
}

(client.c)
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<strings.h>
#include<stdlib.h>

//define port to access (use 8080 instead)


#define PORT 8080

int main()
{
int sockfd;
struct sockaddr_in serv;
char message[255],fflush;

//create socket
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
perror ("Error : Socket Failed!, Get File Descriptor
Error!! : \n");
return 1;
}

//set address family (biasanya simbolik : AF_INET)

serv.sin_family = AF_INET;

//set port number


//htons digunakan untuk mengkonversi
//port number dalam host byte
//ke port number dalam network byte order
serv.sin_port = htons(PORT);
//127.0.0.1
serv.sin_addr.s_addr = inet_addr("localhost");

//perform connect to server


if(connect(sockfd,(struct sockaddr*)&serv,sizeof(serv))==-1)
{
perror("Error: Connect Error!\n");
return 1;
}

//set all buffer message to zero


bzero(message,sizeof(message));

do
{
printf("Input message [1..50 char]: ");
scanf("%[^\n]",message);
scanf("%c",&fflush);

//simple validation
}while(strlen(message)<1 || strlen(message)>50);

//sending message via socket descriptor


if(write(sockfd,message,sizeof(message))==-1)
{
perror("Error : Write failed!\n");
return 1;
}

bzero(message,sizeof(message));

//You can!" The longer answer is,


//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read and write

if(read(sockfd,message,sizeof(message))==-1)
{
perror("Error : Read failed!\n");
return 1;
}

printf("Message from server : %s\n",message);


printf("Length of message : %d character\n",strlen(message));

close(sockfd);

return 0;
}
Jalankan program di atas dengan cara :
gcc server.c

o server

./server

gcc client.c o client


./client

./client

Chapter 05
Client
Server with Broadcast

Objective:
. Unicast
. Multicast
. Broadcast
Learning Outcome:
. Memilih teknik dan protocol pemrogram jaringan untuk pemecahan suatu masalah
. Memperhitungkan beberapa program dengan protokol yang umum dipergunakan pada
jaringan komputer.
. Menjelaskan berbagai macam komponen yang berhubungan dengan pemrograman jaring
an

5.1. Unicast
Unicast merupakan suatu teknik dimana data dikirimkan merupakan jenis paket yang
berasal dari satu titik. Paket ini memiliki 1 MAC address pengirim dan satu MAC
address
penerima.
Jaringan-jaringan yang bersifat unicast : http (kasusnya terlihat ketika kita br
owsing),
telnet, ftp, smtp, pop3, dsb.

5.2. Multicast

Multicast merupakan suatu teknik dimana data yang dikirimkan mempunyai lebih dar
i 1
titik dimana titik yang mendengarkan dan mengirimkan berasal dari resources yang
berbeda.
Konsep ini terpakai di siaran radio dan televisi (kebetulan penulis pernah mengg
eluti
usaha ini)
Analoginya: untuk siaran televisi, jika kita hendak menonton siaran khusu, maka
kita
harus merubah frekuensi televisi ke frekuensi yang tepat (dan ingat, berjuta-jut
a orang
bisa mendengarkan radio yang sama, dan jenis frekuensi radio ada banyak)

5.3. Broadcast

Jenis ketiga adalah jenis broadcast. Jenis ini merupakan jenis teranyar untuk di
bahas dan
dipelajari. Jika Anda telah mempelajari Jaringan Komputer, apalagi jika sudah be
rtemu di
kelas sang penulis mungkin sudah mengenal ini.
Broadcast biasanya dikirimkan untuk menyatakan keberadaan suatu layanan. Selain
itu
broadcast juga dapat digunakan untuk pencarian sebuah titik pada jaringan. Terut
ama
pada konsep DHCP (Dynamic Routing, yang tentunya tidak dibahas disini).
Contoh nyata penggunaan prinsip ini adalah : NETBIOS yang dikirimkan oleh Window
s
yang berisi nama komputer dan workgroup.

Kalau di jalan di sekitar Jakarta, ibarat tukang sayur yang sedang menjajakan sa
yurnya.
Ia biasa berteriak, .Sayuurr, ssayurr !.. Untuk membuat orang mengetahui tentang
dia dan apa yang ia jual/punya.

Pada jaringan komputer, umunya diberikan suatu titik khusus untuk broadcast yait
u pada
bagian x.x.x.255 (untuk memperkecil pengaruh broadcast agar jaringan tidak menga
lami
traffic yang disebabkan oleh broadcast semata). 255 = FF:FF:FF:FF:FF:FF
Pada bagian ini akan dijelaskan code mengenai broadcast terlebih dahulu. Dibatas
i
sampai sini dahulu.
Contohnya adalah pada chatting MIRC. Terdapat broadcasting untuk memberitahukan
ada user yang masuk. Berikut contoh potongan codenya:
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<strings.h>
#include<string.h>
#include<netinet/in.h>
#include<pthread.h>

//set port pada 8080


#define PORT 8080

int count=0;
int save_socket[10];

void * thread_proc(void * arg)


{
char in[255],name[100],out[255],fflush;
int newsocketfd;
int i;

newsocketfd = (int) arg;

//set new socket


save_socket[count] = newsocketfd;
count++;

//set zero bit pada name


bzero(name,sizeof(name));

//You can!" The longer answer is,


//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read and write

if(read(newsocketfd,name,sizeof(name)) == -1)
{
perror("Error: Read failed! \n");
return 1;;
}

sprintf (out, "Computer: %s join...", name);

for(i=0; i<10; i++)


{
if(save_socket[i]!=-1 && save_socket[i]!=newsocketfd)
{
//sending message via socket descriptor
if(write(save_socket[i],out,sizeof(out))<0)
{
perror("Error : Write failed!\n");
return 1;
}
}
}
printf ("New client entered : %s\n", name);

while(true)
{
//clear zero in
bzero(in,sizeof(in));

//You can!" The longer answer is,


//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read and
write

if(read(newsocketfd,in,sizeof(in))<=0)
{
perror("Error: Read failed! \n");

return 1;
}

if(strcmp(in,"exit")==0)
break;
printf("Received message from %s : %s [%d char]\n",name,
in, strlen(in));

bzero(out,sizeof(out));

sprintf (out, "%s : %s [%d char]", name, in, strlen(in));

for(i=0; i<10; i++)


{
if(save_socket[i]!=-1 && save_socket[i]!=newsocketfd)
{
//sending message via socket descriptor
if(write(save_socket[i],out,sizeof(out))<0)
{
perror("Write Error");
}
}
}
}
sleep(1);
printf ("%s sign out from chat\n", name);
sprintf (out, "%s sign out...", name);

for(i=0; i<10; i++)


{
if(save_socket[i]!=-1 && save_socket[i]!=newsocketfd){
if(write(save_socket[i],out,sizeof(out))<0)
{
perror("Write Error");
}
}
}
close(newsocketfd);
}

int main()
{
struct sockaddr_in serv,cli;
int sockdf,newsocketfd;
int client_size, i;
char message[255],name[100],fflush;

pthread_t thread_id;

sockdf = socket(AF_INET,SOCK_STREAM,0);

if(sockdf==-1)
{
perror("Error : Create Error\n");
return 0;
}

//put zero bit


bzero(&serv,sizeof(serv));

//set address family (biasanya simbolik : AF_INET)


serv.sin_family= AF_INET;

//set port number


//htons digunakan untuk mengkonversi
//port number dalam host byte
//ke port number dalam network byte order
serv.sin_port = htons(PORT);

//memasukan server addres


//INADDR_ANY untuk menujuk IP server dimana server running
serv.sin_addr.s_addr = INADDR_ANY;

//aktivasi menyatakan di port mana saya aktif


//pada game jaringan seperti Counter-Strike dan sejenisnya
//inilah yang memberitahukan "connect to 192.168.5.10 port 1120"
//Bind server to port
//Jika langsung listen(), lupakan baris ini
if(bind(sockdf,(struct sockaddr*)&serv,sizeof(serv)) == -1)
{
perror("Error: Bind to port Failed!\n");
return 1;
}

//Bagian menunggu panggilan dari client, listetening


//listen(sockfd, backlog)
//backlog = jumlah maksimal client connect
//biasanya maksimal 20
//tapi cenderung dipilih 5 atau 10
if(listen(sockdf,5)==-1)
{
perror("Error: Listen Failed!");
return 1;
}

for(i=0; i<10; i++)


{
save_socket[i] = -1;
}

system ("clear");
printf ("MIRC Simple Server\n");
printf ("================\n\n");

while(true){
client_size = sizeof(cli);

//"Thank you for calling port 3490."


//That what accept used for
//read chapter 1 carefully and you will
//understand
newsocketfd = accept(sockdf,(struct
sockaddr*)&cli,(socklen_t*)&client_size);

//int accept(int sockfd, struct sockaddr *addr, socklen_t


*addrlen);
//return -1 if error
if(newsocketfd == -1)
{
perror("Error : Accept Error!\n");
return 1;
}

//create thread
if(pthread_create(&thread_id,NULL,thread_proc,(void*)newsocketfd)
<0)
{
perror("Error : Create Thread Error\n");
return 1;
}
pthread_detach(thread_id);
}
//close socket
close(sockdf);

return 0;
}
Di atas adalah program server, berikut ini program clientnya.

#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<strings.h>
#include<string.h>
#include<netinet/in.h>
#include<pthread.h>

//set port to 8080


#define PORT 8080

void * thread_proc(void * arg)


{
int sockfd=(int)arg;
char message[255];

while(true)
{
//set all buffer message to zero
bzero(message,sizeof(message));

//You can!" The longer answer is,


//"You can, but send() and recv() offer
//much greater control over your data transmission.
//Because it using file descriptor, so it can read and
write
if(read(sockfd,message,sizeof(message))<=0)
{

perror("Error: Read failed! \n");


//return 1;
}
printf("Message sent: %s\n",message);
}
}

int main()
{
struct sockaddr_in serv;
int sockfd;

char message[255],name[100],fflush,ip[15];
pthread_t thread_id;

printf("Input Server IP of computer: ");


scanf("%s",ip);
scanf("%c",&fflush);

//get the file descriptor


//socket adalah system call di UNIX
//int socket(int domain, int type, int protocol);
//domain:
// AF_UNIX (former) atau AF_INET (later)
//type:
// SOCK_STREAM atau SOCK_DGRAM
//protocol:

//0 = UDP or TCP will be controlled by system.


sockfd = socket(AF_INET,SOCK_STREAM,0);

//return -1 if error
if(sockfd == -1)
{
perror ("Error : Socket Failed!, Get File Descriptor
Error!! : \n");
return 1;
}

//set address family (biasanya simbolik : AF_INET)


serv.sin_family = AF_INET;

//set port number


//htons digunakan untuk mengkonversi
//port number dalam host byte
//ke port number dalam network byte order
serv.sin_port = htons(PORT);

//memasukan server addres


serv.sin_addr.s_addr = inet_addr(ip);

//perform connect to server


if(connect(sockfd,(struct sockaddr*)&serv,sizeof(serv)) == -1)
{
perror("Error: Connect Error!\n");
return 1;
}

printf("Input chat User ID : ");


scanf("%[^\n]",name);
scanf("%c",&fflush);

if(write(sockfd,name,sizeof(name))<=0)
{
perror("Error: Write Error!\n");
return 1;
}

system ("clear");

printf ("MIRC Simple Client\n");


printf ("================\n\n");

printf ("'exit' for quit chat\n\n");

if(pthread_create(&thread_id,NULL,thread_proc,(void*)sockfd)<0)
{
perror("Error: Thread Error\n");
return 1;
}

do
{
bzero(message,sizeof(message));

scanf("%[^\n]",&message);
scanf("%c",&fflush);

//sending message via socket descriptor


if(write(sockfd,message,sizeof(message))<=0)
{
perror("Error : Write failed!\n");
return 1;
}
} while (strcmp(message,"exit")!=0);

//close socket
close(sockfd);

return 0;
}
Question and task:
1. Apakah fungsi program diatas?
2. Tunjukan outputnya!
3. Apa fungsi dari write();
If you wanna be master in socket, update that source code to recv() and send();

Chapter 06
Client Server with Winsock

Objective:
. WSADATA
. Winsock Client
. Winsock Server

Learning Outcomes:
. Memilih teknik dan protocol pemrogram jaringan untuk pemecahan suatu masalah
. Memperhitungkan beberapa program dengan protokol yang umum dipergunakan pada
jaringan komputer.
. Menjelaskan berbagai macam komponen yang berhubungan dengan pemrograman jaring
an

6.1. WSADATA

WSADATA adalah sebuah struct yang terdiri dari:

typedef struct WSAData {


WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR *lpVendorInfo;
} WSADATA, *LPWSADATA;
wVersion : Menunjukan versi dari socketnya
szDescription : Deskripsi socket
Untuk lebih mengerti perihal Windows socket bukalah :
http://msdn.microsoft.com/en-us/library/ms741563(v=vs.85).aspx
Untuk pengertian dasar Windows Socket (WinSock) telah dijelaskan di chapter 1
(chapter perkenalan)

6.2. Winsock Client

Berikut ini adalah program dasar untuk Windows Socket (Client)


#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>

#include <stdio.h>

// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib


#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

#define DEFAULT_BUFLEN 512


#define DEFAULT_PORT "27015"

int __cdecl main(int argc, char **argv)


{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;

char *sendbuf = "This is a test message";


char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;

// Validate the parameters


if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}

ZeroMemory( &hints, sizeof(hints) );


hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

// Resolve the server address and port


iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}

// Attempt to connect to an address until one succeeds


for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

// Create a SOCKET for connecting to server


ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n",
WSAGetLastError());
WSACleanup();
return 1;
}

// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr>ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}

freeaddrinfo(result);

if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}

// Send an initial buffer


iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}

printf("Bytes Sent: %ld\n", iResult);

// shutdown the connection since no more data will be sent


iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}

// Receive until the peer closes the connection


do {

iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);

if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());

} while( iResult > 0 );

// cleanup
closesocket(ConnectSocket);
WSACleanup();

return 0;
}

6.3. Winsock Server

Berikut ini adalah program dasar untuk Windows Socket (Server)


#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>

#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>

// Need to link with Ws2_32.lib


#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")

#define DEFAULT_BUFLEN 512


#define DEFAULT_PORT "27015"

int __cdecl main(void)


{
WSADATA wsaData;
int iResult;

SOCKET ListenSocket = INVALID_SOCKET;


SOCKET ClientSocket = INVALID_SOCKET;

struct addrinfo *result = NULL;


struct addrinfo hints;

int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);

return 1;
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

// Resolve the server address and port


iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}

// Create a SOCKET for connecting to server


ListenSocket = socket(result->ai_family, result->ai_socktype,
result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}

// Setup the TCP listening socket


iResult = bind( ListenSocket, result->ai_addr, (int)result>ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}

freeaddrinfo(result);

iResult = listen(ListenSocket, SOMAXCONN);


if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}

// Accept a client socket


ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}

// No longer need server socket


closesocket(ListenSocket);

// Receive until the peer shuts down the connection


do {

iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);


if (iResult > 0) {
printf("Bytes received: %d\n", iResult);

// Echo the buffer back to the sender


iSendResult = send( ClientSocket, recvbuf, iResult, 0 );
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n",
WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();

return 1;
}

} while (iResult > 0);

// shutdown the connection since we're done


iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}

// cleanup
closesocket(ClientSocket);
WSACleanup();

return 0;
}

References :
Steven, W. Richard. 1998. UNIX Network Programming. Prentice Hall: London.
Windows Programming MSDN:
http://msdn.microsoft.com/en-us/library/ms741563(v=vs.85).aspx
http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#lowlevel
http://www.linuxhowtos.org/C_C++/socket.htm

http://www.tenouk.com/Winsock/Winsock2story.html

You might also like