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
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);
//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" };
//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);
//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;
//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);
//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 };
// 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);
//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 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; }
//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);
//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);
//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
//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);
//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; }
//"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);
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>
//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);
//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);
//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
//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;
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
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
//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);
//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
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
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
//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);
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
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); } }
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
//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);
//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
// 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")
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; }
// 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; }
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 {
// 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; }