Вы находитесь на странице: 1из 67

i | P a g e

Practicum Module (Diktat Praktikum)


Subject: H0483 Network Programming
Hands on Lab




Lecturer: D4460 Henry Chong, S.Kom.


September 2011 (Odd Semester 2011/2012)
ii | P a g e

Information in this document, including URL and other Internet Web site references, is
subject to change without notice. This document supports a preliminary release of 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 means
(electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, 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 names, e-
mail addresses, logos, people, places and events depicted herein are fictitious, and no
association with any real company, organization, product, domain name, email address,
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 trademarks of
their respective owners.

iii | P a g e

Table of Contents


TABLE OF CONTENTS ............................................................................................................................................. III
PREFACE ............................................................................................................................................................... IV
OVERVIEW ............................................................................................................................................................. V
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
REFERENCES ......................................................................................................................................................... 62
iv | P a g e

Preface


Puji syukur pada Tuhan Yang Maha Esa atas selesainya diktat kuliah Network
Programming untuk Jurusan Teknik Informatika, Fakultas Ilmu Komputer, Binus University -
Jakarta. Diktat yang terdiri dari 6 bab ini disusun berdasarkan referensi materi yang terdapat
references (daftar pustaka).
Diktat Network Programming ini merupakan hal yang penting untuk dipelajari.
Mengingat Network programming merupakan dasar penting untuk pemrograman antar client-
server. Adapun, diktat ini telah dirancang sedemikian rupa sehingga diharapkan dapat
memudahkan pembaca (mahasiswa/dosen) untuk membaca dan memahaminya.
Dalam penyusunan diktat ini, saya juga mengakui mungkin saja tidak sempurna. Untuk
itu kritik yang disertai dengan saran yang membangun dimana dapat membantu diktat ini ke arah
penyempurnaan, saya terima dengan tangan terbuka.
Akhir kata, Henry mengucapkan terima kasih kepada semua pihak yang telah membantu
penyiapan, penulisan, dan penerbitan diktat ini. Selain itu, besar harapan penulis kiranya diktat
ini dapat dijadikan referensi, petunjuk, dan atau dapat dipergunakan dengan sebaik-baiknya.


Jakarta, October 2011


Henry Chong
D4460

v | P a g e

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

1 | P a g e





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 jaringan
2 | P a g e

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. Database Server
2. Printer
3. Modem
4. Fax
5. 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.
3 | P a g e


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 users
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
(listen)

Client
Request
via
Port

Server

Client
Response
via
Port
4 | P a g e


[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 memberikan
response terhadap request yang ada secara bersamaan (concurrent).

I terativeServer adalah server yang dapat menghandle banyak server dan memberikan
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 )


5 | P a g e

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 bersifat
sederhana yang dideskripsikan pada Data yang dikirim bersifat datagram yang memiliki
panjang seperti record. Pengecekan data sukses tidaknya hanya menggunakan checksum
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 )
6 | P a g e

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 ).








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

Dengan :
c = client
s = server

7. Application
6. Presentation
5. Session
4. Transport
3. Network
2. Data Link
1. Physical
7 | P a g e

1.5. TCP/IP Layer
Pada layer TCP/IP, koneksi TCP dan UDP terdapat pada ( layer 3 ).

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 menggunakan
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
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)
8 | P a g e

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. Untuk
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 dibagi
menjadi 5 bagian:
1. Blocking I/O
2. Non-Blocking I/O
9 | P a g e

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

Question:
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. What is struct?
7. Mention The IANA Port List!
8. Mention and explain about system client-socket step!





10 | P a g e

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

11 | P a g e



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

12 | P a g e

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. Input Operations
2. Output Operations
3. Accepting Incoming connections
4. Initiate outgoing connection

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

13 | P a g e

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

Untuk Accepting incoming connection dapat menggunakan fungsi accept.

Sedangkan, Initiating outgoing connections menggunakan fungsi connect.

Bagaimana caranya melakukan Non Blocking System?
Non Blocking System dapat dilakukan dengan mengunakan str_cli menggunakan fungsi
select. Fungsi ini dipakai untuk menentukan kondisi dimana deskriptor sedang readable
atau writeable.

Untuk menunjukan kinerja client server pada komputer yang sama dapat menggunakan
fungsi fork.

Untuk sistem yang lebih canggih (TCP threeway-handshake), dapat menggunakan
nonblocking connect. Hal tersebut tidak dibahas dalam buku ini tapi Anda dapat temukan
dengan mudah di internet.

2.3 Bzero memory operations
Fungsi Bzero adalah menuliskan sejumlah null bytes ke tujuan. Jika bzero(char *dest, int
nbytes) diisi dengan bzero(nama,10) maka nama akan dimasukan sejumlah 10 null bytes.

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");

14 | P a g e

//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", exampleword1);
15 | P a g e

printf ("Example Word2: %s\n", exampleword2);
printf ("Example Word3: %s\n", exampleword3);
maka tercetak
Example Word1: Sample string
Example Word2: Sam%h%
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
"IIIve 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
16 | P a g e

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 dikenal
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 Most
Significant Byte pada address terkecil.

Little Endian


Dari tabel ini didapatkan kesimpulan bahwa pada Little Endian, kita menyimpan the 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!!


Address 1009 1010 1011 1012
Value D C B A
17 | P a g e

#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
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
18 | P a g e

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

#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 menyajikannya,
sebab ini adalah dasarnya
char *inet_ntoa(struct in_addr in);
input berupa struct in_addr, untuk memahami perhatikan prototype struct
dibawah.
return IP (misalnya : 10.22.69.69)
o n for network
o a for ascii
o jadi ntoa berarti network to ascii

19 | P a g e

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];
};



20 | P a g e

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.

21 | P a g e

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
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. Apa itu sa_family? Jelaskan!
3. Apa itu sin_addr? Jelaskan!
4. Apa itu program client-server?
5. Apa itu bzero?

22 | P a g e





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 jaringan
23 | P a g e

3.1. Definisi Program Client-Server
(Seperti pengertian pada Chapter 1) 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.
3.2. Program Client Server Dasar
Pada bagian ini akan dikemukakan code beserta dengan penjelasannya. Bagian ini akan
mempermudah Anda mempelajarinya. Setiap bagian code akan diberikan comment dan
penjelasan dasar yang mengarahkan Anda untuk mengerti.
3.2.1. Program Server
Dalam program server yang umumnya ada adalah:
1. Socket
2. Bind
3. Listen
4. Accept
5. Read & Write
6. 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;
24 | P a g e

}

//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
25 | P a g e

//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++;
}

26 | P a g e

} 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;
27 | P a g e


//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)
28 | P a g e

{
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;
}




29 | P a g e

3.3. Program Client Server with Thread
Pada bagian ini akan dikemukakan code beserta dengan penjelasannya. Bagian ini akan
mempermudah Anda mempelajarinya. Setiap bagian code akan diberikan comment dan
penjelasan dasar yang mengarahkan Anda untuk mengerti. Yang membedakan adalah
disediakan thread, dimana thread memungkinkan sebuah program untuk membagi
dirinya menjadi beberapa task yang bisa 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);
30 | P a g e


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:
31 | P a g e

// 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
32 | P a g e

//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*)newsoc
kfd) == -1)
{
perror("Error : Create Thread Error\n");
return 1;
}

//detach thread
pthread_detach(thread_id);
}

//close socket
close(sockfd);

return 0;
}


33 | P a g e

3.3.2. Program Client with thread
Merupakan program client (sebelumnya) dengan server 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
34 | P a g e

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);
35 | P a g e


//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 telah
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





36 | P a g e




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 jaringan

37 | P a g e

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 request
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 untuk
menghandle semua request (tanpa perlu fork()).

4.2. FD_SET
Select() pada penjelasan diatas bekerja ketika ada perubahan pada file descriptor (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 descriptor
(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 input.

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)

38 | P a g e

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 input.

4.5. FD_CLR
FD_CLR digunakan untuk membersikan semua bit pada file deskriptor (fd) dalam fdset.
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 input.

4.6. Example of Select with input trigger
Berikut ini adalah contoh yang bisa dipakai untuk lebih memahami select.
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;

39 | P a g e

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? Jelaskan jalannya program!

4.7. Example of select implemented in client server
Berikut ini adalah contoh program menggunakan select pada client server:
(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()
{
40 | P a g e

//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
41 | P a g e

//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
42 | P a g e

//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))
43 | P a g e

{
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;
}



44 | P a g e

(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);

45 | P a g e

//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

46 | P a g e





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 jaringan





47 | P a g e

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 browsing),
telnet, ftp, smtp, pop3, dsb.

5.2. Multicast
Multicast merupakan suatu teknik dimana data yang dikirimkan mempunyai lebih dari 1
titik dimana titik yang mendengarkan dan mengirimkan berasal dari resources yang
berbeda. Konsep ini terpakai di siaran radio dan televisi.
Analoginya: untuk siaran televisi, jika kita hendak menonton siaran khusus, maka kita
harus merubah frekuensi televisi ke frekuensi yang tepat (dan ingat, berjuta-juta 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 dibahas dan
dipelajari. Broadcast biasanya dikirimkan untuk menyatakan keberadaan suatu layanan.
Selain itu broadcast juga dapat digunakan untuk pencarian sebuah titik pada jaringan.
Terutama pada konsep DHCP (Dynamic Routing, tidak dibahas disini).
Contoh nyata penggunaan prinsip ini adalah : NETBIOS yang dikirimkan oleh Windows
yang berisi nama komputer dan workgroup.
Kalau di jalan di sekitar Jakarta, ibarat tukang sayur yang sedang menjajakan sayurnya.
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 yaitu pada
bagian x.x.x.255 (untuk memperkecil pengaruh broadcast agar jaringan tidak mengalami
traffic yang disebabkan oleh broadcast semata). 255 = FF:FF:FF:FF:FF:FF
48 | P a g e

Pada bagian ini akan dijelaskan code mengenai broadcast terlebih dahulu. Dibatasi
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)
{
49 | P a g e

//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)
{
50 | P a g e

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)
51 | P a g e

{
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>
52 | P a g e

#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)
{
53 | P a g e

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)
{
54 | P a g e

perror("Error : Write failed!\n");
return 1;
}
} while (strcmp(message,"exit")!=0);

//close socket
close(sockfd);

return 0;
}
Question:
1. Apakah fungsi program diatas?
2. Tunjukan outputnya!
3. Apa fungsi dari write() dan read()?
Exercise:
1. Ubahlah source code diatas untuk broadcast dengan menggunakan recv() dan send()!


55 | P a g e






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
jaringan
56 | P a g e

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

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";
57 | P a g e

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) {
58 | P a g e

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>
59 | P a g e

#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
60 | P a g e

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;
61 | P a g e

}

} 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;
}





62 | P a g e

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

Вам также может понравиться