Tải bản đầy đủ (.pdf) (31 trang)

Xây dựng ứng dụng bắt gói tin cho mạng quản lý (Giang Quốc Minh) - 2 potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (315.33 KB, 31 trang )


Chng 3: H qun tr c s d liu MySQL
36
3.3. S dng MySQL
3.3.1. Lnh mysql
ây là lnh thâm nhp trình qun lý c s d liu và a ra các
nh qun tr khác .
Cú pháp
mysql u username p password databasename
Ví d
Truy xut c s d liu packet voi username la “pac” va
password la “ket”.
$ mysql –I pac –p ket packet
3.3.2. Lnh mysqladmin
Là công c chính ca ngi qun tr c s d liu vi 2 tham s -u,-
p . Vi mysqladmin có mt s lnh qun tr sau
• create databasename : to csdl
• drop database name :xóa c s d liu
• password newpassword : i mt khu
• status: thông tin v trng thái hin hành ca trình ch
• version cho bit thông tin v phiên bn ca trình ch my sql
3.3.3. Lnh mysqlshow
Lnh này cho bit thông tin v database. Nu không có tham s s
hin th toàn b database, ngc i nu có tham s là tên database thì
hin th tt c các bng trong database.
u tham s là tên database và tên bng thì toàn b tên các ct
trong bng sc hin th
u tham s là tên database,tên bng,tên ct thì thông tin ca ct s
c lit kê.

Chng 3: H qun tr c s d liu MySQL


37
3.3.4. Lnh grant
p quyn cho ngi dùng database
Cú pháp :
grant privilege on object to user[user-password] [opt]
• privilege là quyn cp cho tài khon ngi dùng bao gm:
§ Alter : quyn thay i bng và file ch mc
§ Creat : quyn to bng vàdatabase
§ Delete : quyn xoá d liu trong database
§ Drop : quyn xoá database
§ Index : quyn qun lý ch mc index
§ Insert : quyn chèn d liu mi vào
§ Select : quyn xem d liu
§ Update : quyn cp nht d liu
§ All : tt c các quyn
• Object : databasename.table
Có th dùng databasename.* s tác ng n mi bng
trên databasename.
u ý: mysql cho phép cp quyn trên database cha có
cho mt ngi dùng sau này s to
• User : username.host
Ví d rick@”%”
• Password : nu grant ta mi user ta t password bng
cách thêm identyfied by password
• Ví d : to mi user khtn vi password cntt toàn quyn trên
database tên packet(packet có th cha có)
mysql>grant all on packet.* to khtn@”%” indentified by cntt

Chng 3: H qun tr c s d liu MySQL
38

3.3.5. Lnh Revoke
Lnh này dùng  c quyn ngi dùng
Cú pháp:
revoke privilege on object from user
3.3.6. Ví d v to mt c s d liu
o c s d liu packet vi username là khtn và password la cntt :
$mysql>grant all on packet.* to khtn@ identified by cntt;
nh trên c thc hin vi t cách qun tr root ca MySQL.
(Thoát v du nhc lnh $mysql>quit )
Ri gõ tip các lnh sau:
$mysql u khtn p cntt
$ mysql>create database packet;
$mysql>use packet (s dng database tên packet)
Bây gi mi truy vn sql u lác ng lên database packet.
3.4. Lp trình MySQL trên ngôn ng C
Mt s hàm thng dùng khi lp trình vi MySQL
4.4.1 mysql_init
Khi to cu trúc x lý kt ni
Cú pháp :
MYSQL *mysql_init (MYSQL *old_connect)
Tham s:
• old_connect =NULL :to kt ni mi
• old_connect khác NULL :tái kt ni vi con tr old_connect

Chng 3: H qun tr c s d liu MySQL
39
3.4.2 mysql_real_connection
Thc hin kt ni vt lý n máy ch ni Mysql sever ang chy
Cú pháp :
MYSQL *mysql_real_connect(MYSQL *connection ,

const char* server_host, const char * sql_username,
const char *sql_pass, const char* db_name,
unsigned port_num ,const char * unit_socket_name ,
unsigned int flag )
Tham s :
• Connection : trn cu trúc MYSQL c khi to bi hàm
mysqlconnect.
• Server_host : a ch IP ca máy ch ni dch vu mysql
server ang chy.
• sql_username,sql_pass : là i s chng thc quyn ng
nhp h thng
• db_name : tên ca database
• port_num : s hiu cng mysql dùng (mc nh bng 0)
• unit_socket_name kiu socket (mc nh NULL)
• flag: kiu giao thc s kt ni

Chng 3: H qun tr c s d liu MySQL
40
3.4.3 mysql_query
Thc thi câu lnh sql query.
Cú pháp:
int mysql_query(MYSQL *connect,const char* query)
Tham s:
• query : câu lnh sql cn thc hin
Kt qu tr v
• Bng 0 nu thc thi thành công
• Bng 1 nu tht bi
3.4.4. mysql_affected_rows
Cho bit s dòng bnh hng sau lnh query
Cú pháp :

my_ulonglong mysql_affected_rows(MYSQL *connection)
Khi s dng hàm này phi ép kiu giá tr tr v là unsigned long
3.4.5. mysql_store_result
y giá tr tr v sau khi gi hàm mysql_query a vào cu trúc
MYSQL_RES
Cú pháp :
MYSQL_RES *mysql_store_result(MYSQL -*connection)
3.4.6. mysql_fetch_row
y ra mt dònh d liu t MYSQL_RES . Bn cng có th di
chuyn n 1 dòng d liu bt kì nh hai hàm mysql_row_seek và
mysql_row_tell.
Cú pháp :
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

Chng 3: H qun tr c s d liu MySQL
41
3.4.7. mysql_row_seek
Di chuyn n v trí offset và tr v v trí con tr trc ó
Cú pháp :
MYSQL_ROW_OFFSET myql_row_seek(
MYSQL_RES *result MYSQL_ROW_OFFSET offset)
3.4.8. mysql_free_result
Gii phóng tài nguyên.
Cú pháp:
void mysql_free_result (MYSQL_RES *result)

Chng 4: Lp trình socket
42
Chng 4: Lp trình socket
4.1. Gii thiu v lp trình socket

Khi vit ng ng và có nhu cu tng tác vi mt ng ng khác,
chúng ta thng da vào mô hình khách/ ch (client/server). Theo mô hình
này, ng ng có kh ng phc  hoc cung cp nhng thông tin gì ó gi
là ng ng ch (trình ch hay server). ng ng gi yêu cu n trình ch
c i là ng ng khách (trình khách hay client). M rng hn na, server
có th là mt máy tính vi cu hình nh còn client là rt nhiu máy con khác
ni vào máy ch.
Nh vy, trc khi yêu cu mt ch  ca trình ch thc hin iu gì
ó, trình khách (client) phi có kh ng kt ni c vi trình ch. Quá trình
kt ni này c thc hin thông qua mt c ch tru tng hóa i là socket
(m ch là “c ch cm”). Kt ni gia trình khách và trình ch ng t
nh vic cm phích in vào  cm in. Trình khách thng c coi nh
phích cm in, còn trình ch c coi nh  cm in, mt  cm có th cm
vào ó nhiu phích in khác nhau ng nh mt máy ch có th kt ni và
phc  cho rt nhiu máy khách.
Nu kt ni thành công thì trình khách và trình ch có th trao i d
liu vi nhau, thc hin các yêu cu v trao i d liu.
4.2. Nguyên lý hot ng a socket
u tiên server m mt  cm socket. ây ch là quá trình h iu hành
phân b tài nguyên  chun  kt ni. Dùng hàm socket()  to “ cm”
cho trình ch server.
Tip n, ng ng khách bit n  cm socket a trình ch, n
phi t cho server ch mt cái tên. Nu trên máy c b và da vào h thng
file a UNIX hay Linux, n có th t tên cho socket nh là mt tên file

Chng 4: Lp trình socket
43
(vi y  ng dn). n ch cn t tên còn ng dn thng t trong
th c /tmp hay /usr/tmp. i vi giao tip ng thông qua giao thc
TCP/IP tên a socket c thay th bng khái nim cng (port). Cng là mt

s nguyên 2 bytes (khong 65000 cng n có th chn t cho socket) thay
th cho tên tp tin. Nu trình khách và trình ch nm trên hai máy khách
nhau, giao thc TCP/IP còn yêu cu xác nh thêm a ch IP  kt ni n
máy ch xa.
Sau khi ã ch nh tên hoc s hiu port cho socket, n i hàm bind()
 ràng buc hay t tên chính thc cho socket a trình ch. Tip n là ch
kt ni t phía trình khách, trình ch s gi hàm listen()  to hàng i nhn
các kt ni do trình khách a n. Nu có yêu cu kt ni t phía trình
khách, trình ch gi hàm accept()  tip nhn yêu cu a trình khách.
accept()  to mt socket vô danh khác (unnamed socket), cm kt ni a
trình khách vào socket vô danh này và thc hin quá trình chuyn d liu trao
i gia khách ch. Socket c t tên trc ó vn tip c hot ng 
ch nhn yêu cu t trình khách khác.
i giao tip c ghi thông qua socket ng n gin nh vic dùng
lnh read/write  c ghi trên file. Nu file da vào s mô  (file descriptor)
 xác nh socket cn c ghi cho hàm read/write.
Phía trình khách ch cm o mt socket vô danh, ch nh tên và v trí
socket a trình ch. Yêu cu kt ni bng hàm connect() và c ghi, truy
xut d liu a socket bng lnh read/ write hoc lnh send/ recv.

Chng 4: Lp trình socket
44
4.3. Lp trình vi socket
4.3.1. Các thuc tính a socket
Socket c nh ngha da trên 3 thành phn thuc tính( attribute)
ó là: vùng( domain), kiu( type) và giao thc( protocol). Socket còn cn
c vào mt a ch kt hp vi nó. a ch này ph thuc vào vùng a
socket và thng c i là dòng giao thc (protocol family). Ví d
nh dòng giao thc theo h thng file a Sun thng ly tên file làm
ng dn a ch, trong khi giao thc TCP/IP i ly a ch IP (32 bits)

 tham chiu và thc hin kt ni vt lý.
4.3.1.1. Vùng( domain)
Vùng dùng xác nh  tng ng ni giao tip a Socket
din ra. Vùng giao tip Socket thông ng nht hin nay là
AF_INET hay gia tip socket theo chun ng Internet. Chun này
s dng a ch IP  xác nh nút kt ni vt lý trên ng. Ngoài
ra, nu n ch cn giao tip c b, n có th dùng vùng giao tip
theo chun a Sun AF_UNIX, ó là dùng ng dn và h thng
file  t tên và xác nh kt ni gia hai hay nhiu ng ng.
Chng n nh ví d trên, chúng ta ã thc hin bng cách t tên
cho socket là server_socket, và Linux ã to ra file server_socket
ngay trên th c hin hành (hay trong th c m /tmp tùy theo
phiên n a Linux và UNIX). Tuy nhiên vùng giao tip
AF_UNIX li ít c s dng trong thc t. Ngày nay hu ht các
ng ng ng s dng socket u theo vùng AF_INET là ch yu.
Chúng ta  bàn sâu v phân vùng này ngay sau ây.
Vùng AF_INET nh ã nêu s dng c ch IP (Internet
Protocol) là mt ch ngha s 32 bits  xác nh kt ni vt lý. S
này thng c vit  dng nhòm nh 192.168.1.1, 203.162.42.1

Chng 4: Lp trình socket
45
hay 127.0.0.1 là các a ch IP hp l. a ch IP có th c ánh 
thành mt tên d nh n nh www.yahoo.com
hay
www.microsoft.com
, chúng c i là tên vùng (domain name).
Vic ánh  a ch IP thành tên vùng thng do máy ch DNS
(Domain Name Server) thc hin. Tuy nhiên, n ng có th t
ánh  tên vùng ngay trên mày c b bng cách s dng tp tin d

liu /etc/hosts.
Socket theo dòng giao thc IP s dng port (s hiu cng) 
t tên cho mt socket. Cng dùng  phân bit d liu gi n 
chuyn cho ng ng nào. n hình dung nu a ch IP dùng 
xác nh c máy hay ni kt ni vt lý  a d liu n thì
cng là a ch ph dùng  gi chính xác d liu n ni ng ng
cn. iu này do trên mt máy có th có nhiu ng ng cùng chy
và cùng s dng trùng s cng. Do cng là mt giá tr nguyên 2
bytes nân n có th s dng khong 65000 cng  t do t cho
socket. Tr các s hiu cng n ting nh FTP, Web ã nêu  phn
trên n không nên s dng, còn thì bn có th chn s cng ln
n 1024 m cho socket a ung ng.
M socket theo AF_INET không khác my so vi AF_UNIX
ngoài vic t tên và ch nh s hiu cng. Ví d:
/* M socket theo kt ni IP */
server_sockfd = socket (AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr(“127.0.0.1”);
server_address.sin_port = 1234;

Chng 4: Lp trình socket
46
Ngoài vùng giao tip AF_UNIX và AF_INET, n còn có th
gp AF_ISO dành cho chun giao thc ng theo ISO hay AF_NS
dành cho h thng ng Xerox, tuy nhiên chúng không c s
ng thng xuyên, cho nên ta  không  cp n chi tit.
5.3.1.2. Kiu socket(type)
Vi mi vùng domain a socket, n có th có nhiu cách
giao tip. Có hai kiu giao tip kiu giao tip in hình s là giao
tip mt chiu (SOCK_DGRAM) và giao tip o m hai chiu

(SOCK_STREAM). D liu khi chuyn i c óng thành tng
gói (data package hay datagram). SOCK_STREAM và
SOCK_DGRAM qui nh cách chuyn gói d liu theo hai cách
nh sau:
SOCK_STREAM luôn gi kt ni và bo m gói thông tin
gi i c chuyn n ích và nhn y . Sau khi nhn xong d
liu, ni nhn  gi thông tin phn hi cho ni gi và quá trình gi
ch c xác nhn hoàn tt khi nhn c y  thng tin gi nhn
 c hai phía khách ch. Kiu truyn d li socket này trong vùng
giao thc ng Internet AF_INET c  là giao thc truyn
TCP. Khi kt hp vi c ch nh tuyn theo a ch IP chúng c
i tt là TCP/IP. Kt ni và truyn d liu theo cách này tuy o
m nhng tn nhiu tài nguyên a h thng do kt ni phi duy
trì và theo dõi thng xuyên.
SOCK_DGRAM cách gi nhn d liu này ch din ra mt
chiu. Trình khách, ni gi d liu i không cn bit trình ch (ni
nhn) có nhn c gói d liu y  hay không. Trình ch khi
nhn c d liu ng không cn thông báo hay xác nhn vi trình
khách là d liu ã nhn xong. Cách gi này có v không an toàn

Chng 4: Lp trình socket
47
nhng bù li thc hin nhanh và không tiêu tn nhiu tài nguyên 
duy trì kt ni và kim tra d liu nhn gi. Kiu truyn d liu
socket này trong vùng giao thc ng Internet AF_INET c i
là giao thc truyn UDP (User Datagram Protocol). Khi kt hp vi
 ch nh tuyn theo c ch IP chúng c i tt là UDP/IP. Do
tính cht không m o nên UDP c dùng nhiu trong ng vi
c ích thông báo hay gi tin tin n mt nhóm máy tính nào ó
trong ng. Nó ít khi c dùng trong các ch  cn s chính xác

cao nh gi nhn file hay kt nói c s d liu.
4.3.1.3. Giao thc a socket( protocol)
Giao thc là cách qui c gi nhn d liu giia hai hay nhiu
máy tính trong mng. Tùy theo mi kiu gi nhn d liu mà ta có
các giao thc khác nhau. Hin nay kiu gi nhn theo giao thc
TCP và UDP là s dng nhiu nht. Tuy nhiên iu này không bt
buc, TCP và UDP ch là cách cài t cho vùng socket AF_INET
theo giao tip Internet mà thôi. Ví d, ban có th cài t mt giao
thc khác thay cho UDP áp ng cho cách chuyn d liu không
o m. Mõi kiu socket u có giao thc mc nh áp ng cho
nó. Trong tt  các hàm socket sau này, tùy chn protocol nu có
yêu cu n có th t giá tr 0 yêu cu s dng giao thc mc
nh.
Trong các ví d phn sau ta ch tp trung nghiên cu v vùng
socket AF_INET và a ch IP thay cho vùng AF_UNIX. Vi
AF_INET i ng ng ng a n u có th giao tip c
vi nhau bt k chúng ang chy trên Windows, Linux hay UNIX.

Chng 4: Lp trình socket
48
4.3.2. To socket
H thng cung cp cho n hàm socket()  to mi mt socket.
Hàm socket() tr v s nguyên int cho bit s mô  hay nh danh dùng
 truy cp socket sau này.
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
Tham s domain ch nh vùng hay  a ch áp t cho socket.
domain có th nhn mt trong các giá tr sau:
AF_UNIX M socket kt ni theo giao thc file (xut nhp socket da

trên xut nhp (file) a UNIX/Linux
AF_INET M socket theo giao thc Internet (s dng a ch IP  kt
ni)
AF_IPX Vùng giao thc IPX (ng Novell)
AF_IS Chun giao thc ISO
AF_NS Giao thc Xerox Network System
ng 4-1 Các giá tr ca domain
Hu nh n ch s dng AF_UNIX và AF_INET là chính. Các
vùng giao thc khác ã li thi và hin nay ít còn c s dng.
Tham s type trong hàm socket() dùng ch nh kiu giao tiép hay
truyn d liu a socket. n có th ch nh bng SOCK_STREAM
dùng cho truyn d liu o m hoc SOCK_GRAM dùng cho truyn
không o m.

Chng 4: Lp trình socket
49
Tham s protocol dùng  chn giao thc áp ng cho kiu socket(
trong trng hp có nhiu giao thc áp ng cho mt kiu truyn). Tuy
nhiên n ch cn t giá tr 0 (ly giao thc mc nh). AF_INET ch cài
t mt giao thcduy nht cho các kiu truyn SOCK_STREAM và
SOCK_DGRAM ó là TCP và UDP.
Nu o socket thành công, hàm  tr v s nh danh socket(
descriptor). n s dng s nh danh này trong tt  các li i truy
xut socket khác nh read/write. S này tng t nh s nh danh file
mà bn thng dùng  c và ghi file. c/ ghi vào socket ng ng
ngha vi gi và nhn d liu gia trình khách và trình ch.
4.3.3. nh a ch cho socket
Khi socket ã c o ra, n ch cn ch nh a ch và tên cho
socket. Mt socket cn phi có a ch và tên  các trình khách có th
tham chiu n. Tùy mi vùng giao thc mà cách ánh a ch có th

khác nhau.
Ví d khi n dùng vùng giao thc AF_UNIX da trên h thng tp
tin, a ch socket c nh ngha trong cu trúc sockaddr_un a file
include sys/un.h nh sau:
struct sockaddr_un{
sa_family_t sun_family; /* AF_UNIX */
char sun_path []; /* ng dn */
};

Chng 4: Lp trình socket
50
Trong Linux sa_family_t c nh ngha là kiu short. sun_path là
ng dn  to tp tin socket.
Vùng AF_UNIX c s dng nhiu trong các ng ng c b
trên t máy vì nó ph thuc vào ng dn tp tin tuyt i a h
iu hành.
Thc t bn  dùng AF_INET vi cu trúc a ch c nh ngha
trong sockadd_in a file include netinet/in.h nh sau:
struct sockadd_in{
short in sin_family; /* AF_INET */
unsigned short int sin_port; /* s cng */
struct in_addr sin_addr; /* a ch IP */
};
Cu trúc in_addr mô  a ch IP c nh ngha nh sau:
struct in_addr{
unsigned long int s_addr;
};
Nh n thy a ch IP là mt s long (4 bytes hay 32 bits). ây
ng chính là cu trúc a ch cho mt chng trình giao tip vi nhau
qua ng Internet.

Trên quan im a lp trình ng ng, cho dù socket có nh a
ch theo vùng nào i chng na mt khi ã m c socket, n ch cn
xem socket nh mt tp tin và thc hin thao tác read/write trên ó(
ng ng vi send và receive trên Winsock a Microsoft).

Chng 4: Lp trình socket
51
4.3.4. t tên cho socket
Sau khi ã nh a ch, n ch cn t tên cho socket. i vi
AF_UNIX c ch chính là ng dn, còn tên chính là tên tp tin  to
socket. i vi vùng giao thc AF_INET a ch chính là s IP còn tên
chính là s hiu cng (sin_port) trong cu trúc sockaddr_in. Khi ã gán
thông tin y  cho socket n cn i hàm bind()  rabgd buc nhng
thông tin này cho socket ã m ra trc ó.
#include <sys/socket.h>
int byte (int socket, const struct sockaddr *address, size_t address_len);
Hàm h thng bind() s dng các thông tin trong cu trúc address
 gán cho socket s nh danh socketd tr v bi hàm socket() trc ó.
Tham s address_len cho bit chièu dài a cu trúc (struct sockaddr*)
truyn vào hàm. n lu ý sockaddr là cu trúc tng quát cho 
sockaddr_un và sockaddr_in
Khi ràng buc thành công bind()  tr v tr 0. Nu không hàm  tr v
-1 và errno  cha mt trong các li sau:
Mã li Mô 
EBADF S mô  file không hp l
ENOTSOCK S mô  file không dành cho socket
EINVAL S mô  file tham chiu n mt socket ã có.
EADDRNOTAVAIL a ch không xác nh
EADDRINUSE a ch và cng ràng buc ã b mt socket khác
chim ng

ng 4-2 Các mã li a hàm bind()

Chng 4: Lp trình socket
52
Nu n m socket thuc vùng AF_UNIX errno có th nhn thêm
các li sau:
Mã li Mô 
EACCESS Không th to file cho socket do không có
quyn o file
ENOTDIR,
ENAMETOOLONG
Tên file không hp l
ng 4-3 Các mã li a domain AF_UNIX
Ràng buc tên socket là bc quan trng nht  socket a n có
kh ng nhìn thy và truy xut c t các ng ng bên ngoài.
Mt socket nu cha c t tên i là socket vô danh ( unnamed
socket).
4.3.5. o hàng i cho socket
 ón nhn các kt ni chuyn n, socket trình ch phi o ra
mt hàng i (queue). c ích a hành i là u i các kt ni cha
c trình ch x lý kp. Hàm h thng listen()  thc hin công vic
này.
#include <sys/socket.h>
int listen(int socketd, int backlog);
Tham s socketd cho bit s mô  socket cn o hàng i. backlog
là s kt ni ti a c phép a vào hàng i. Nu mt kt ni n
trình ch trong khi ã có backlog kt ni trc ó cha x lý thì kt ni
này  b tht i. Lý do hàng i ã y, trình ch server không mun
nhn thêm kt ni na. Thông thng backlog mang giá tr 5 là s trung
bình kh thi nht.


Chng 4: Lp trình socket
53
Hàm listen()  tr v 0 nu o hàng i thành công, nu tht i tr
tr v s là -1 và bin errno  cha tr EBADF, EINVAL, hoc
ENOTSOCK.
4.3.6. Ch và chp nhn kt ni
Mt khi ã to c socket, t tên cho nó và chun  xong hàng
i  tip nhn kt ni, công vic sau cùng là ch kt ni a trình
khách gi n. n i hàm accept()  thc hin công vic này.
#include <sys/socket.h>
int accept(int socketd, struct sockaddr *address, size_t
*address_len);
Hàm h thng accept()  tr v khi có mt trình khách mun kt
ni vi  cm socket ch nh s mô  socketd. Kt ni a trình khách
trc ht c t vào hàng i. Khi accept() phát hin ra có socket
trong hàng i, nó s t ng ly a ch ca máy khách t vào cu trúc
address, chiu dài tht s ca cu trúc a ch tr v trong bin
address_len. Tip n accept() o ra mt socket vô danh. Kt qu tr v
a accept() là s mô  cho socket vô danh, n có th s dng s này
 liên c vi trình khách. Socket vô danh mi này có cùng kiu vi
socket t tên ang lng nghe trên hàng i.
Do cu trúc struct sockaddr không có nh cho nên n cn thit lp
kích thc va  tip nhn a ch trình khách. Nu a ch trình
khách dài hn không gian n dành cho cu trúc sockaddr, phn d ra 
 ct  .

Chng 4: Lp trình socket
54
Nu cha có kt ni nào trong hàng i, accept()  dng i ch –

block( trình ch s không thc thi các lnh k tip) cho n khi có kt
ni a client gi n. Bàn có th thay i c ch ch này bng cách i
hàm fcntl() iu chnh và thêm vào c O_NONBLOCK cho socket nh
sau:
int flags=fcntl(socketd, F_GETFL, 0);
fcntl(socketd, F_SETFL, O_NONBLOCK | flags);
Sau khi t c này cho socket, hàm accept()  không dng i ch
khi n i nó. accept()  tr v ngay s mô  cho socket nu có kt ni
trong hàng i, nu không nó s tr v -1 và thc thi dòng lnh k tip.
4.3.7. Yêu cu kt ni
Trình ch ca n thng thc hin chac nng o, t tên, ch kt
ni bnh các hàm socket(), bind(), và accept(). Tuy nhiên phía trình
khách n gin hn, n ch cn i hàm connect()  yêu cu kt ni
vi trình ch. connect() c khai báo nh sau:
#include <sys/socket.h>
int connnect(int socketd, const struct sockaddr *address,
size_t address_len);
Tham s socketd là s mô  tr v bi hàm socket(). address là cu
trúc a ch tr n socket a trình ch. address_len là chiu dài a
bin cu trúc address. Kt qu tr v ca hàm là 0 nu thành công và
ngc i là -1. Trong trng hp -1, bin errno  cha mt trong nhng
tr sau:

Chng 4: Lp trình socket
55
Mã li Mô 
EBADF S mô  socket truyn cho hàm không hp l
EALREADY Kêt ni ã c thit lp trc ó
ETIMEOUT Quá thi gian ch kt ni
ECONNREFUSED Trình ch server t chi kt ni

ng 4-4 Mã li a hàm connect()
Nu kt ni không thành công hàm connect()  có gng ch kt ni
i. Nu sau mt s ln kt ni không thành công connect()  tr v li
ETIMEOUT.
ng t accept() n có th i ch  ch ca hàm connect()
bng cách i fcntl() t i c ENONBLOCK. Bng cách này, khi kt
ni không thành công  ln u tiên, hàm connect()  không ch lp
i kt ni. Hàm  kt thúc và tr v mã li ngay lp tc.
4.3.8. óng kt ni
ng t nh x lý trên file. n có trách nhim óng các kt ni
ã to ra bng cách g hàm close(). óng kt nói  gii phóng tài
nguyên và bo m d liu ã chuyn i hoàn tt  c hai u gi và
nhn.
#include <sys/socket.h>
int close(int sockd);
i vi  hai phía trình khách và trình ch, n nên i close()
óng socket khi lnh read tr v tr 0 (không còn d liu  c).

Chng 4: Lp trình socket
56
Thng thì close() tr v ngay tc khc, tuy nhiên có th close()  i
vào trng thái ch (block) nu scoket a n thit lp kiu kt ni hai
chiu (SOCK_STREAM) cùng vi tùy chn SOCK_LINGER và d liu
ang  trnh thái cha chuyn ht. Tùy chn SOCK_LINER  c 
cp sau.
4.3.9. Giao tip bng socket
Chúng ta va xem qua các hàm h thng dùng o và x lý socket,
gi ây ta có th tr li nhng ví d v s dng socket  th n.
Nhã nêu, n nên s dng socket theo vùng AF_INET thay cho
AF_UNIX. Socket da trên h thng file thng gp phi mt s vn 

nh chúng ch c truy xut trên h thng file ch nh a
UNIX/Linux. Vic phân quyn cho phép c ghi file ng là mt vn .
Thng file socket o ra trong th c hin hành hoc th c m
/tmp và bn phi cho phép hu nh toàn quyn truy cp các th c này
 socket hot ng. Vi AF_INET thì vn  này không phát sinh,
AF_INET da vào cng và a ch IP  kt ni. ng ng a n trên
Linux s dng AF_INET  d chuyn i sang Windows hn là
AF_UNIX.
Trong AF_INET, khi o mi mt socket trên trình ch, n phi
chn mt s hiu cng t cho socket. Vic chn s hiu cng phi loi
tr nhng cng ã c các ng ng khác s dng. n có th tham
kho tp tin /etc/services, ây là tp tin vn n lit kê danh sách các
ch  và cng ã c  dành s dng, s cng a n không nên
trùng vi nhng s ã có trong danh sách này. Ban ng không th s
ng các cng nh n 1024, chúng dành cho các ch  ca h thng.
Giao tip ng không òi i phi kt ni vi mt h thng ng
tht s. Ngay trên mt máy, n có th s dng giao tip ng  liên

Chng 4: Lp trình socket
57
c gia các tin trình ang chy. Nu cn s a ch IP, n có th s
ng s 127.0.0.1, ây là a ch IP “hi qui” (loop back) thng dùng
cho các ng ng c b. Vi a ch này, d liu gi i  quay v úng
a ch ban u, có ngha là máy gi và máy nhn c xem là mt. Do
tính cht c bit này, nu trình khách trên máy c b gi d liu n
trình ch theo IP 127.0.0.1 thì trình ch cng trên máy này  nhn c
d liu và hi âm i. Nu máy n hòa ng, n nên i ngi qun tr
ng  xin mt a ch IP thích hp.
a ch mng IP thng khó nh, n có th yêu cu socket tip
nhn mt tên gi nh khách thay cho s IP. Chng n localhost hay

my.computer.home thay cho 127.0.0.1. Tp tin vn n /etc/hosts cha
các danh sách chuyn i này. Ví d, n có th dùng trình son tho vi
hay gnotepad sa ni dung tp tin này nh sau:
127.0.0.1 localhost
127.0.0.1 my.computer.home
207.46.131.91 www.microsoft.com
Nh n thy, mt a ch IP có th ánh  bng nhiu tên khác
nhau (a ch IP và tên thng cách nhau bng khong trng hay tab).
Thng a ch IP 127.0.0.1 c i là localhost và không có gì tr
ngi nu n d nh t cho nó mt cái tên khác chng n nh
my.computer.home. Các a ch Web mà bn thng thy nh
www.yahoo.com
hay www.microsoft.com là các a ch toàn cu c
qun lý bi t chc quc t InterNIC.  bit mt tên i ng vi mt
a ch IP có tn i hay không, n có th gi lnh ping nh sau:

Chng 4: Lp trình socket
58
$ ping localhost
PING (127.0.0.1) from 127.0.0.1 : 56 (84) bytes of data.
64 bytes from (127.0.0.1) : icmp_seq=0 ttl=255 time=67 usec
64 bytes from (127.0.0.1) : icmp_seq=0 ttl=255 time=48 usec
64 bytes from (127.0.0.1) : icmp_seq=0 ttl=255 time=51 usec
4.4. S dng socket trong ng ng minh a
Phn lp trình socket này  c s dng  thc hin vic trao i
thông tin gia thành phn client và server trong phn ng ng minh
a.
 th thành phn client  dùng socket kt ni n thành phn
server. Sau khi kt ni thành công client  gi các lnh nh Start
Capture, Stop Capture, Get Filter n server, server nhn các lnh này,

thc hin xong nó s tr li kt qu thc hin là thành công hay tht i
cho client.

Phn 3: Xây dng ng dng th nghim PacketCap
59
PHN 3: XÂY DNG NG NG TH NGHIM PACKETCAP
Chng 5. Phân tích và thit k PacketCap
Chng 6. Cài t và th nghim
Chng 7. Tng kt

Chng 5: Phân tích và thit k PacketCap
60
Chng 5: Phân tích và thit k PacketCap
5.1. Kho sát hin tng
Hin nay có rt nhiu phm mm bt gói tin nh Tcpdump, Microsoft
Network Monitor, Ethereal Trong ó phn mm ngun m Ethereal ni bt
vi nhiu u im nh chy trên nhiu h iu hành, h tr bt gói tin theo
nhiu giao thc khác nhau
Các phn mm này có hn ch chung là khi chúng ang bt các gói tin
thì chúng ta không th c, phân tích các thông tin bt c, hay nói cách
khác khi kt thúc quá trình bt các gói tin ri thì mi phân tích các thông tin
này c.
Nhng phn mm này không h tr vic ghi kt qu vào c s d liu,
mà ch u vào các file có cu trúc theo nh ng riêng a chúng. Nu file
này có kích thc ln thì vic tìm kim, x lý các thông tin  phân tích  rt
chm.
Nhng phn mm này ch chy trên môi trng desktop là ch yu do ó
không cho phép cu hình t xa (ví d: u chnh b lc , thit lp ng dn
u tr trên mng ….t xa. Hin nay các phn mm này ang c phát trin
sang mô hình client/server).

Trong khi ó thì nhu cu ngi qun tr mng rt a dng:
• n có thông tin v lu lng mng  u chnh bng
thông theo yêu cu ca khách hàng cng nh phát hin
trc các s c nu c.
• Theo dõi hành ng truy cp và xâm nhp mng bt hp
pháp.
• t c hành ng trên nên là online (phân tích và u
khin) nu c.

×