TRƯỜNG CAO ĐẲNG CÔNG NGHỆ THÔNG TIN TP.HCM
LẬP TRÌNH ỨNG DỤNG MẠNG BÀI 2
P TRÌNH SOCKET LLẬẬP TRÌNH SOCKET LẬP TRÌNH SOCKET
GIẢNG VIÊN: VÕ TẤN DŨNG
g n ũ D n ấ T õ V
:
V G
KHÁI NIỆM SOCKET KHÁI NIỆM SOCKET
truyền thiết lậplập kếtkết nốinối truyền pháp đđểể thiết (client) trình yêuyêu cầucầu dịchdịch vụvụ (client)
trình cung
cung cấpcấp dịchdịch vụvụ (server)
(server) trêntrên
Socket làlà mộtmột phphươươngng pháp (cid:132)(cid:132) Socket thông giữagiữa mộtmột chchươươngng trình thông vàvà mộtmột chchươươngng trình LAN, WAN hay Internet. mạngmạng LAN, WAN hay Internet. (cid:132)(cid:132) TrTrưướcớc khikhi yêuyêu cầucầu dịchdịch vụvụ từtừ máymáy chủchủ thì
khách thì máymáy khách trình kếtkết nốinối nàynày đưđượcợc
thực hiệnhiện thông
thông quáquá mộtmột ccơơ chếchế trừutrừu ttưượngợng
phải kếtkết nốinối đđếnến máymáy chủchủ. . QuáQuá trình phải Java thực Java Socket.. hóahóa gọigọi làlà Socket thông qua Socket (cid:132)(cid:132) ViệcViệc kếtkết nốinối thông
qua Socket cầncần haihai thông
thông tin
tin chủchủ
yếuyếu đđóó làlà đđịaịa chỉchỉ củacủa máymáy cầncần kếtkết nốinối vàvà sốsố hiệuhiệu trình dịchdịch vụvụ.. cổng củacủa chchươươngng trình cổng
2
g n ũ D n ấ T õ V
:
V G
PHẦN 1 InetAddress LLớớpp InetAddress Lớp InetAddress & & llớớpp URLURL & lớp URL
g n ũ D n ấ T õ V
:
V G
InetAddress LớpLớp InetAddress
(cid:132) Lớp InetAddress được sử dụng để biểu diễn các địa chỉ IP trong một ứng dụng mạng. Lớp này được sử dụng bởi hầu hết các lớp mạng, bao gồm Socket, ServerSocket, URL, DatagramSocket, DatagramPacket,…
(cid:132) Nó bao gồm hai trường thông tin: hostName (một đối tượng kiểu String) và address (một số kiểu int). Các trường này không phải là trường public, vì thế ta không thể truy xất chúng trực tiếp.
4
g n ũ D n ấ T õ V
:
V G
InetAddress LớpLớp InetAddress
constructor chocho lớplớp
không cócó cáccác constructor nhiên, , cócó baba phphươươngng thức
thức tĩnhtĩnh trảtrả vềvề
InetAddress.getByName(String InetAddress InetAddress.getByName(String
InetAddress.getAllByName(String InetAddress[] [] InetAddress.getAllByName(String
InetAddress.getLocalHost()()
(cid:132)(cid:132) LớpLớp InetAddress InetAddress không InetAddress. . TuyTuy nhiên InetAddress InetAddress:: cáccác đđốiối ttưượngợng InetAddress –– public static public static InetAddress hostname) hostname) public static InetAddress –– public static hostname) hostname) public static InetAddress –– public static (cid:132)(cid:132) TấtTất cảcả cáccác phphươươngng thức
InetAddress InetAddress.getLocalHost thức nàynày đđềuều thực
tới thực hiệnhiện kếtkết nốinối tới
thông tin
trong tin trong
server DNS cụccục bộbộ đđểể biếtbiết đưđượcợc cáccác thông server DNS đđốiối ttưượngợng InetAddress InetAddress..
5
g n ũ D n ấ T õ V
:
V G
InetAddress LớpLớp InetAddress
(cid:132) Ví dụ: Phương thức getByName này nhận tên của hostname làm tham số và trả về đối tượng kiểu InetAddress
try{
InetAddress dc =InetAddress.getByName(“www.microsoft.com”); System.out.println(dc);
} catch(UnknownHostException e) {
System.err.println(e);
}
6
g n ũ D n ấ T õ V
:
V G
(cid:132)(cid:132) VíVí dụdụ 1:Viết
nhận hostname hostname từtừ đđốiối dòng dòng lệnh lệnh vàvà in IP in rara đđịaịa chỉchỉ IP
InetAddress LớpLớp InetAddress trình nhận 1:Viết chchươươngng trình ttươươngng ứngứng vớivới hostname
hostname đđóó..
main(String[] [] argsargs) )
dung: java TimDCIP
("Cach susu dung: java
java.net.*;.*; import java.net import TimDCIP public class TimDCIP public class {{ public static void main(String public static void !=1) if(args.length!=1) {try{ if(args.length {try{
System.out.println("Cach
host.getHostName();();
name:"+hostName););
()); IP:"+host.getHostAddress());
{ { System.out.println host = InetAddress.getByName(args[0]); InetAddress host = InetAddress.getByName(args[0]); InetAddress hostName = = host.getHostName String hostName String System.out.println("Host name:"+hostName System.out.println("Host System.out.println("Dia chi chi IP:"+host.getHostAddress System.out.println("Dia } } catch(UnknownHostException {{ chi"); thay diadia chi");
catch(UnknownHostException e)e) System.out.println("Khong timtim thay System.out.println("Khong return; return;
}}
}}
7
g n ũ D n ấ T õ V
:
V G
}}
InetAddress LớpLớp InetAddress
bằng cáchcách gọigọi
CóCó thểthể đđọcọc cáccác trtrưườngờng củacủa InetAddress thức getHostname
InetAddress bằng getAddress():(): getHostname vàvà getAddress getHostName()(): : PhPhươươngng thức
chuỗi biểubiểu diễndiễn hostname
hostname, thì
thức nàynày trảtrả hostname củacủa mộtmột đđốiối ttưượngợng không cócó hostname, thì nónó sẽsẽ
IP củacủa máymáy nàynày ddưướiới dạng
dạng mộtmột xâuxâu kýký tựtự..
(cid:132)(cid:132) public byte[ ]
phphươươngng thức public String getHostName (cid:132)(cid:132) public String vềvề mộtmột chuỗi InetAddress. . NếuNếu máymáy không InetAddress trảtrả vềvề đđịaịa chỉchỉ IP public byte[ ] getAddress chỉchỉ IP mộtmột đđịaịa chỉchỉ IP
IP củacủa mộtmột máymáy, , phphươươngng thức IP ddưướiới dạng
getAddress()() : : NếuNếu bạnbạn muốnmuốn biếtbiết đđịaịa getAddress() () trảtrả vềvề thức getAddress byte. dạng mộtmột mảngmảng cáccác byte.
8
g n ũ D n ấ T õ V
:
V G
InetAddress LớpLớp InetAddress
trình nhập
nhập mộtmột hostName
lệnh vàvà in
in rara dòng
dòng thông
thông báobáo
hostName từtừ đđốiối dòng IP đđóó thuộc
dòng lệnh thuộc lớplớp nàonào..
IP ttươươngng ứngứng vớivới đđịaịa chỉchỉ IP
(cid:132)(cid:132) VíVí dụdụ: : ViếtViết chchươươngng trình chocho biếtbiết đđịaịa chỉchỉ IP java.net.*;.*;
import java.net import PhanLoaiDCIP public class PhanLoaiDCIP public class {{
main(String[] [] argsargs) )
dung: java TimDCIP
host.getHostName();();
name:"+hostName););
()); IP:"+host.getHostAddress());
System.out.println(host+" +" thuoc
chi lop A"); thuoc diadia chi lop A");
System.out.println(host+" +" thuoc System.out.println(host+" +" thuoc
public static void main(String public static void !=1) {{System.out.println("Cach if(args.length!=1) {try{ if(args.length {try{ System.out.println("Cach susu dung: java host = InetAddress.getByName(args[0]); InetAddress host = InetAddress.getByName(args[0]); InetAddress hostName = = host.getHostName String hostName String System.out.println("Host name:"+hostName System.out.println("Host System.out.println("Dia chi chi IP:"+host.getHostAddress System.out.println("Dia host.getAddress();(); byte[] b=host.getAddress byte[] b= i=b[0]>=0?b[0]:256+b[0]; int i=b[0]>=0?b[0]:256+b[0]; int >=1)&(i<=126)) System.out.println(host if((i>=1)&(i<=126)) if((i <=191)&(i>=128)) System.out.println(host if((i<=191)&(i>=128)) if((i <=223)&(i>=192)) System.out.println(host if((i<=223)&(i>=192)) if((i catch(UnknownHostException e) { e) { System.out.println("Khong
thuoc diadia chi lop B"); chi lop B"); chi lop C"); thuoc diadia chi lop C"); System.out.println("Khong timtim thay
chi"); thay diadia chi");
} } catch(UnknownHostException return; return;
}}
}}
9
}}
g n ũ D n ấ T õ V
:
V G
LớpLớp URLURL
java.net.URL làlà mộtmột khái
tài khái niệmniệm vềvề bộbộ đđịnhịnh vịvị tài
(cid:132)(cid:132) LớpLớp java.net.URL thống nhất nguyên thống nguyên
nhất. . MộtMột URL URL gồmgồm 3 3 phần
phần: :
(protocol), thức (protocol),
–– GiaoGiao thức –– Hosname
Hosname ((cócó thểthể làlà mộtmột đđịaịa chỉchỉ hay hay têntên máymáy chủchủ) ) vàvà (port), cổng (port), cổng –– ĐưĐườngờng dẫndẫn (path)
tài liệuliệu (document section)
(path) chỉchỉ đđếnến têntên tậptập tin (filename) hay tin (filename) hay (document section) màmà máymáy client client muốnmuốn
mụcmục tài lấylấy từtừ máymáy chủchủ vềvề. .
: http://www.abc.com:80/xyz/index.html VíVí dụdụ: http://www.abc.com:80/xyz/index.html
10
g n ũ D n ấ T õ V
:
V G
LớpLớp URLURL
constructor sausau::
–– public
protocol, String host, String file) URL(String protocol, String host, String file)
–– public
URL(String protocol, String host,
–– public
port, String file) int port, String file)
public URL(String URL(String urlurl)) MalformedURLException throws MalformedURLException throws public URL(String throws MalformedURLException MalformedURLException throws protocol, String host, int public URL(String MalformedURLException throws MalformedURLException throws public URL(URL u, String s) –– public URL(URL u, String s) MalformedURLException throws MalformedURLException throws
11
g n ũ D n ấ T õ V
:
V G
(cid:132)(cid:132) ĐĐốiối ttưượngợng URL URL cócó cáccác constructor
LớpLớp URLURL
MalformedURLException ) throws MalformedURLException nhất; ; thamtham sốsố củacủa nónó chỉchỉ làlà mộtmột
URL(String urlurl) throws public URL(String (cid:132)(cid:132) public (cid:132)(cid:132) ĐâĐâyy làlà constructor constructor đơđơnn giảngiản nhất chuỗi. . dạng chuỗi
URL ở dạng URL ở
VíVí dụdụ try{ try{
URL u = new URL(“http://www.sun.com/index.html URL u = new
URL(“http://www.sun.com/index.html”);”);
}} catch(MalformedURLException e)e) catch(MalformedURLException {{
System.err.println(e);); System.err.println(e
}}
12
g n ũ D n ấ T õ V
:
V G
LớpLớp URLURL
public URL(String protocol, String host, String file) URL(String protocol, String host, String file) (cid:132)(cid:132) public MalformedURLException throws MalformedURLException throws truyền vàovào gồmgồm 3 3 chuỗi
chuỗi ttươươngng ứngứng vớivới: : giaogiao
(cid:132)(cid:132) ĐĐốiối sốsố truyền
Không nguyên. . Không
thức, hostname thức cócó đđốiối sốsố port (
, hostname vàvà đưđườngờng dẫndẫn đđếnến tài dùng cổng
port (cócó nghĩa
nghĩa làlà dùng
tài nguyên cổng mặcmặc đđịnhịnh).).
VíVí dụdụ try{ try{
URL u = new URL URL u = new URL
(“http”,”/www.sun.com”,”index.html (“http”,”/
www.sun.com”,”index.html”);”);
catch(MalformedURLException e)e){{ }}catch(MalformedURLException
System.err.println(e);); System.err.println(e
}}
13
g n ũ D n ấ T õ V
:
V G
protocol, String host, int
port, String int port, String
LớpLớp URLURL (cid:132)(cid:132) public
phép bạnbạn xácxác đđịnhịnh cổng
cổng mộtmột cáchcách
public URL(String URL(String protocol, String host, MalformedURLException file) throws MalformedURLException file) throws Constructor nàynày chocho phép (cid:132)(cid:132) Constructor int. ràng kiểukiểu int. rõrõ ràng
(cid:132)(cid:132) VíVí dụdụ:: try{ try{
URL u = new URL(“http”,”/www.sun.com”,80,”index.html”); URL u = new URL(“http”,”/www.sun.com”,80,”index.html”);
}} catch(MalformedURLException e)e) catch(MalformedURLException {{
System.err.println(e);); System.err.println(e
}}
14
g n ũ D n ấ T õ V
:
V G
LớpLớp URLURL
MalformedURLException public URL(URL u, String s) throws MalformedURLException
(cid:132)(cid:132) public URL(URL u, String s) throws (cid:132)(cid:132) VíVí dụdụ
URL u1,u2; URL u1,u2; try{ try{
URL(“http://www.macfaq.com/index.html”);”);
URL u1= new URL(“http://www.macfaq.com/index.html URL u1= new URL u2 = new URL(u1,”vendor.html”); URL u2 = new URL(u1,”vendor.html”);
}} catch(MalformedURLException e)e) catch(MalformedURLException {{
System.err.println(e);); System.err.println(e
}}
(cid:132)(cid:132) TênTên file
file sẽsẽ đưđượcợc loại
loại khỏi
khỏi đưđườngờng dẫndẫn củacủa u1, u1, vàvà têntên file
file mớimới
danh sáchsách cáccác file
u2. Constructor nàynày đđặcặc biệtbiệt hữuhữu cùng nằmnằm
qua mộtmột danh
tất cảcả cùng
duyệt qua
file màmà tất
vendor.html đưđượcợc gángán vàovào đđểể tạotạo lênlên u2. Constructor vendor.html íchích khikhi bạnbạn muốnmuốn duyệt trong mộtmột ththưư mụcmục. . trong
15
g n ũ D n ấ T õ V
:
V G
MộtMột sốsố phphươươngng thức
thức khác
khác củacủa lớplớp URLURL
throws IOException
IOException lấylấy vềvề nộinội
getContent(): (): throws
theo đđịaịa chỉchỉ URL URL cócó đưđượcợc..
phần têntên tậptập tin hay
tin hay tài
trong tài liệuliệu nằmnằm trong
thành phần
getFile(): (): lấylấy vềvề thành
thành phần
phần thứthứ haihai
getHost(): (): lấylấy têntên máymáy chủchủ, , ththưườngờng làlà thành
thức, , làlà thành
thành phần
phần thứthứ haihai
getProtocol(): (): lấylấy vềvề têntên giaogiao thức
dung thamtham khảo
khảo thêmthêm trong
trong chuỗi
chuỗi URL URL
public final Object getContent (cid:132)(cid:132) public final Object dung màmà kếtkết nốinối theo dung String getFile (cid:132)(cid:132) String chuỗi đđịaịa chỉchỉ URL.URL. chuỗi String getHost (cid:132)(cid:132) String trong chuỗi chuỗi URL.URL. trong String getProtocol (cid:132)(cid:132) String chuỗi URL.URL. trong chuỗi trong String getPort (cid:132)(cid:132) String String getRef (cid:132)(cid:132) String ((nằmnằm sausau dấudấu # # trong
getPort(): (): lấylấy vềvề sốsố hiệuhiệu cổng cổng.. getRef(): (): lấylấy vềvề nộinội dung trong mộtmột URI)URI)
16
g n ũ D n ấ T õ V
:
V G
VíVí dụdụ vềvề lớplớp URLURL
(cid:132)(cid:132) VíVí dụdụ: : đđoạnoạn mãmã sausau đâđâyy dùng
dùng đđểể lấylấy vềvề nộinội dung
trang dung trang
web web index.html try{ try{
nhập đđểể đđọcọc nộinội dung trang web web trảtrả vềvề từtừ máymáy chủchủ
BufferedReader(new =new BufferedReader(new inStream=new
index.html rara mànmàn hìnhhình dung trang
index.html từtừ máymáy chủchủ cócó đđịaịa chỉchỉ java.sun.com java.sun.com theo đđịnhịnh vịvị URLURL trang web web theo ////mởmở kếtkết nốinối đđếnến trang http://java.sun.com/index.html);); URL o=new URL(URL(http://java.sun.com/index.html URL o=new dung trang luồng nhập ////tạotạo luồng BufferedReader inStream BufferedReader ())); InputStreamReader(o.openStream())); InputStreamReader(o.openStream trang web web index.html //in nộinội dung //in String line; String line; while((line==in.readLine while((line {{
())!=null) in.readLine())!=null)
System.out.println(line);); System.out.println(line
}}
trình mởmở vàvà kếtkết nốinối đđếnến trang trang web web bịbị lỗi lỗi
17
}catch (Exception e) }catch (Exception e) ////quáquá trình {{ System.out.println(e);); System.out.println(e
g n ũ D n ấ T õ V
:
V G
}}
PHẦN 2
Socket CCáácc llớớpp Socket Các lớp Socket
g n ũ D n ấ T õ V
:
V G
MộtMột sốsố lớplớp Socket
Datagram Socket vàvà Datagram
Socket (cid:132)(cid:132) LớpLớp Socket ServerSocket (cid:132)(cid:132) LớpLớp ServerSocket DatagramSocket (cid:132)(cid:132) LớpLớp DatagramSocket DatagramPackage (cid:132)(cid:132) LớpLớp DatagramPackage
(cid:132)(cid:132) ChúChú ý: ý: LậpLập trình
Socket truyền
quan truyền dữdữ liệuliệu sẽsẽ liênliên quan trong mômô hìnhhình Transport (trong truyền tin
thức truyền
tin cậycậy
đđếnến haihai giaogiao thức chiếu 7 7 tầng thamtham chiếu TCP vàvà truyền TCP
trình Socket thức ở ở tầng tầng OSI), không tin
tầng Transport ( OSI), đđóó làlà giaogiao thức tin cậycậy UDP.UDP.
truyền không
19
g n ũ D n ấ T õ V
:
V G
Client Socket class chocho Client Socket class
Socket dùng
dùng tạotạo kếtkết nốinối từtừ máymáy khách
khách đđếnến máymáy chủchủ
khởi dựng
thức sausau::
(cid:132)(cid:132) LớpLớp Socket
dựng bằng host, int
Socket(String host,
ththưườngờng đưđượcợc khởi bằng cáccác phphươươngng thức public Socket(String port) throws int port) throws IOException UnknownHostException, , IOException UnknownHostException
socket TCP vớivới host
host vàvà cổng
cổng xácxác đđịnhịnh, , vàvà thực
thực hiệnhiện
HàmHàm nàynày tạotạo mộtmột socket TCP liênliên kếtkết vớivới host ở host ở xaxa.. public Socket(InetAddress
(cid:132)(cid:132) public
Socket(InetAddress host,
host, int
int port)throws
IOException port)throws IOException
constructor trtrưướcớc, constructor
thông tin
tin làlà đđịaịa chỉchỉ củacủa mộtmột host
cổng port,
socket TCP , constructor nàynày tạotạo mộtmột socket TCP host đưđượcợc xácxác đđịnhịnh bởibởi mộtmột đđốiối ttưượngợng host. tới host.
thực hiệnhiện kếtkết nốinối tới
port, sausau đđóó nónó thực
ngoại lệlệ IOException
IOException nhnhưưngng không
không đưđưaa rara ngoại ngoại lệlệ trong
ngoại lệlệ trong trtrưườngờng hợphợp
TTươươngng tựtự nhnhưư constructor vớivới thông InetAddres vàvà sốsố hiệuhiệu cổng InetAddres NóNó đưđưaa rara ngoại UnknownHostException. Constructor UnknownHostException không kếtkết nốinối đưđượcợc tới không
. Constructor đưđưaa rara ngoại host. tới host.
20
g n ũ D n ấ T õ V
:
V G
(cid:132)(cid:132) public
Client Socket class chocho Client Socket class
(cid:132)(cid:132) public Socket (String host,
localPort) throws
) throws IOException
InetAddress port, InetAddress IOException, ,
thông tin
socket vớivới thông
host đđóó. Socket
tới host ở
IP đưđượcợc biểubiểu tin làlà đđịaịa chỉchỉ IP cổng vàvà thực thực hiệnhiện kếtkết nốinối qua mộtmột giaogiao tiếptiếp mạngmạng
Java sẽsẽ lựalựa chọn
chọn mộtmột cổng
ngẫu nhiên
cổng ngẫu
nhiên cócó sẵnsẵn nằmnằm
bằng 0 0 thì khoảng từtừ 1024
thì Java 65535. 1024 đđếnến 65535. InetAddress host,
host, intint port,
(cid:132)(cid:132) public Socket (
InetAddress port, InetAddress
) throws IOException
localPort) throws
IOException, ,
host lúclúc nàynày
public Socket (String host, intint port, interface, intint localPort interface, UnknownHostException UnknownHostException Constructor nàynày tạotạo rara mộtmột socket Constructor String vàvà mộtmột sốsố hiệuhiệu cổng diễndiễn bởibởi mộtmột đđốiối ttưượngợng String . Socket kếtkết nốinối tới thông qua host ở xaxa thông tới host tới cổng cụccục bộbộ đưđượcợc xácxác đđịnhịnh bởibởi haihai thamtham sốsố sausau. . NếuNếu vàvà sốsố hiệuhiệu cổng localPort bằng localPort trong khoảng trong public Socket (InetAddress interface, intint localPort interface, UnknownHostException UnknownHostException constructor trêntrên ở ở chỗchỗ đđịaịa chỉchỉ củacủa host khác constructor Constructor chỉchỉ khác Constructor InetAddress.. đưđượcợc biểubiểu diễndiễn bởibởi mộtmột đđốiối ttưượngợng InetAddress
21
g n ũ D n ấ T õ V
:
V G
Client Socket class chocho Client Socket class
Socket: thức hỗhỗ trợtrợ chocho lớplớp Socket: getInputStream() throws
IOException:: () throws IOException khách cócó thểthể đđọcọc dữdữ liệuliệu trảtrả vềvề từtừ máymáy chủchủ..
() throws getOutputStream() throws khách cócó thểthể ghighi dữdữ liệuliệu
xuất đđểể máymáy khách
luồng xuất
socket củacủa
getInetAddress()(): : lấylấy đđịaịa chỉchỉ kếtkết nốinối socket
dùng kếtkết nốinối củacủa máymáy chủchủ..
getPort()(): : lấylấy vềvề sốsố cổng
MộtMột sốsố phphươươngng thức InputStream getInputStream (cid:132)(cid:132) InputStream lấylấy vềvề luồng luồng nhập nhập đđểể máymáy khách OutputStream getOutputStream (cid:132)(cid:132) OutputStream IOException: : lấylấy vềvề luồng IOException gửigửi đđếnến máymáy chủchủ.. InetAddress getInetAddress (cid:132)(cid:132) InetAddress máymáy chủchủ.. (cid:132)(cid:132) intint getPort (cid:132)(cid:132) synchronized void close() throws
IOException: : cắtcắt
cổng dùng synchronized void close() throws IOException đđứtứt kếtkết nốinối vớivới máymáy chủchủ
22
g n ũ D n ấ T õ V
:
V G
CácCác VD VD vềvề Socket
Client Socket chocho Client
(cid:132)(cid:132) public
Socket(String host,
port) throws host, intint port) throws
socket TCP IOException:: hàmhàm nàynày tạotạo mộtmột socket TCP
public Socket(String UnknownHostException, , IOException UnknownHostException vớivới host
cổng xácxác đđịnhịnh, , vàvà thực
host vàvà cổng
thực hiệnhiện liênliên kếtkết vớivới host ở
host ở xaxa. .
(cid:132)(cid:132) VíVí dụdụ:: try{ try{
Socket s = new Socket( “www.vnn.vn”,80); Socket s = new Socket( “www.vnn.vn”,80);
}} catch(UnknownHostException e)e){{ catch(UnknownHostException System.err.println(e);); System.err.println(e
}} catch(IOException e){e){ catch(IOException
System.err.println(e);); System.err.println(e
}}
23
g n ũ D n ấ T õ V
:
V G
CácCác VD VD vềvề Socket
Client Socket chocho Client
trình đđểể kiểmkiểm tratra trêntrên 1024
1024 cổng
cổng đđầuầu tiêntiên những
những cổng
cổng nàonào đđangang cócó server
server hoạt
hoạt đđộngộng
java.io.*;.*;
.*; import java.io
main(String[] [] argsargs) )
localhost";";
VíVí dụdụ: : ViếtViết chchươươngng trình import java.net java.net.*; import import PortScanner class PortScanner class public static void main(String {{ public static void String host="localhost {{ String host=" if(args.length>0){>0){ if(args.length
host=args[0]; host=args[0];
}} i=0;i<1024;i++){ for(int i=0;i<1024;i++){ for(int
try{ try{
Socket(host,i););
Socket s=new Socket(host,i Socket s=new System.out.println("Co mot server dang System.out.println("Co
mot server dang hoat
hoat dong
dong trentren cong:"+i
cong:"+i););
}} catch(UnknownHostException e){e){ catch(UnknownHostException System.err.println(e);); System.err.println(e
}} catch(IOException e){e){ catch(IOException
System.err.println(e);); System.err.println(e
}}
}}
}}
}}
24
g n ũ D n ấ T õ V
:
V G
Client Socket chocho Client
thực hiệnhiện kếtkết nốinối vớivới máymáy chủchủ cócó đđịaịa
luồng xuất
nhập đđểể đđọcọc
CácCác VD VD vềvề Socket VíVí dụdụ: : đđoạnoạn mãmã sausau sẽsẽ thực chỉchỉ ““my.testing.server thông tin vàvà gửigửi thông
my.testing.server” ” vàvà mởmở rara haihai luồng theo sốsố cổng tin đđếnến máymáy chủchủ theo
xuất nhập 1234. cổng 1234.
try{ try{
Socket me=new Socket(“my.testing.server”,1234); Socket me=new Socket(“my.testing.server”,1234);
tin trảtrả vềvề từtừ máymáy chủchủ kếtkết nốinối
thông tin ////luồng luồng nhập nhập đđểể đđọcọc thông in = new DataInputStream in = new DataInputStream ()); DataInputStream(me.getInputStream()); DataInputStream(me.getInputStream
thông tin
xuất đđểể ghighi thông
tin gửigửi đđếnến máymáy chủchủ
////luồng luồng xuất out = new DataOutputStream out = new DataOutputStream ()); DataOutputStream(me.getOutputStream()); DataOutputStream(me.getOutputStream
}catch (Exception e) {System.out.println(e }catch (Exception e) {
System.out.println(e); }); }
25
g n ũ D n ấ T õ V
:
V G
ServerSocket LớpLớp ServerSocket ServerSocket đưđượcợc tạotạo trêntrên máymáy chủchủ, , dùng
LớpLớp ServerSocket
dùng đđểể tạotạo khách. . MộtMột sốsố
kếtkết nốinối từtừ phíaphía máymáy chủchủ đđếnến cáccác máymáy khách hàmhàm củacủa lớplớp ServerSocket ServerSocket::
(cid:132)(cid:132) HàmHàm dựng
dựng ServerSocket(int port làlà sốsố hiệuhiệu cổng
ServerSocket phải
phải lắng
nghe lắng nghe
ServerSocket(int port) throws port) throws cổng màmà ServerSocket khách gởigởi đđếnến..
IOException: : port IOException đđểể biếtbiết những
những kếtkết nốinối từtừ phíaphía máymáy khách Socket accept() throws IOException (cid:132)(cid:132) HàmHàm Socket accept() throws
dừng lại
tin kếtkết
lại chờchờ đđợiợi chocho đđếnến khikhi nhận Socket củacủa máymáy khách
IOException: : phphươươngng thông tin nhận đưđượcợc thông khách nnơơii cócó yêuyêu cầucầu nốinối
thật sựsự dừng thức nàynày thật thức nốinối vàvà sẽsẽ trảtrả vềvề đđốiối ttưượngợng Socket vàovào máymáy chủchủ..
dùng đđểể
public void close() throws IOException
IOException: : dùng
(cid:132)(cid:132) HàmHàm public void close() throws client máymáy chủchủ cắtcắt đđứtứt mọimọi kếtkết nốinối đđếnến cáccác client
26
g n ũ D n ấ T õ V
:
V G
ServerSocket LớpLớp ServerSocket
luôn luôn
lắng nghe
nghe kếtkết nốinối
ServerSocket trêntrên máymáy chủchủ luôn ServerSocket từtừ máymáy khách
(cid:132)(cid:132) VíVí dụdụ: : đđoạnoạn mãmã sausau sẽsẽ tạotạo mộtmột đđốiối ttưượngợng luôn lắng 1234: cổng 1234:
khách gửigửi đđếnến qua
qua sốsố cổng
try{ try{
tại đâđâyy đđểể chờchờ đđợiợi sựsự kếtkết nốinối
lại tại
dừng lại
server sẽsẽ dừng
trình server server.accept();();
server=new ServerSocket(1234); ServerSocket server=new ServerSocket(1234); ServerSocket Socket client; Socket client; ////chchươươngng trình client=server.accept client= ////cócó mộtmột kếtkết nốinối gửigửi đđếnến từtừ phíaphía máymáy khách khách connection”); System.out.println(“Accept connection”); System.out.println(“Accept ////xửxử lýlý cáccác yêuyêu cầucầu dịchdịch vụvụ //…//… //…//… ////cắtcắt đđứtứt cáccác kếtkết nốinối client.close();(); client.close server.close();(); server.close } catch (Exception e){ System.out.println(e } catch (Exception e){
); } System.out.println(e); }
27
g n ũ D n ấ T õ V
:
V G
DatagramSocket LớpLớp DatagramSocket
(cid:132)(cid:132) LớpLớp nàynày dùng
DatagramPackage) ) theo
chuyển mộtmột góigói dữdữ liệuliệu ((biểubiểu diễndiễn thức theo giaogiao thức
nhận không bảobảo đđảmảm đưđượcợc nhận
truyền. . MộtMột sốsố
lỗi trêntrên đưđườngờng truyền
DatagramSocket:: thức củacủa DatagramSocket DatagramSocket() throws
() throws SocketException
khởi SocketException: : khởi
port) throws SocketException
SocketException: :
DatagramSocket(int port) throws dựng đđểể tạotạo kếtkết nốinối UDP UDP vớivới sốsố hiệuhiệu portport
receive(DatagramPackage p) p)
–– public void synchronized IOException: : nhận
nhận góigói dữdữ liệuliệu vềvề
dùng đđểể chuyển bằng đđốiối ttưượngợng DatagramPackage bằng UDP. DữDữ liệuliệu đưđượcợc gửigửi đđii không UDP. đđầyầy đđủủ vàvà cócó thểthể bịbị lỗi phphươươngng thức public DatagramSocket –– public dựng đđểể tạotạo kếtkết nốinối UDPUDP dựng public DatagramSocket(int –– public khởi dựng khởi public void synchronized receive(DatagramPackage throws IOException throws public void synchronized close(): : đđóngóng kếtkết nốinối
–– public void synchronized close()
28
g n ũ D n ấ T õ V
:
V G
DatagramPackage LớpLớp DatagramPackage
chứa dữdữ liệuliệu gửigửi đđii trêntrên mạngmạng theo
theo kếtkết nốinối
LớpLớp nàynày dùng
chứa mộtmột góigói chứa
chứa cáccác thông
thông tin
chiều tin nhnhưư dữdữ liệuliệu, , chiều cổng màmà từtừ đđóó góigói dữdữ liệuliệu đưđượcợc gửigửi đđii. . MộtMột
IP vàvà sốsố cổng
[ ], intint lenlen)): : tạotạo rara góigói dữdữ
chứa trong
chiều dàidài làlà lenlen..
[ ], intint lenlen, ,
DatagramPackage(byte bufbuf[ ], trong biếnbiến bufbuf cócó chiều DatagramPackage(byte bufbuf[ ],
thức trêntrên nhnhưưngng
port): : ttươươngng tựtự phphươươngng thức
iaddr, , intint port)
chứa trong
trong góigói
getAddress()(): : trảtrả vềvề đđịaịa chỉchỉ chứa
thực sựsự chứa
chứa trong
trong góigói..
getData()(): : trảtrả vềvề dữdữ liệuliệu thực
chiều dàidài góigói dữdữ liệuliệu..
port chứa
chứa trong
trong góigói dữdữ liệuliệu
dùng chứa DatagramSocket. . MộtMột góigói cócó thểthể chứa DatagramSocket dàidài góigói, , cáccác đđịaịa chỉchỉ IP sốsố phphươươngng củacủa lớplớp nàynày làlà:: public DatagramPackage(byte (cid:132)(cid:132) public liệuliệu chứa public DatagramPackage(byte (cid:132)(cid:132) public InetAddress iaddr InetAddress port. cócó thêmthêm đđịaịa chỉchỉ máymáy đđíchích vàvà sốsố hiệuhiệu port. InetAddress getAddress public InetAddress (cid:132)(cid:132) public dữdữ liệuliệu.. public byte[ ] getData public getLength public getPort
(cid:132)(cid:132) public byte[ ] (cid:132)(cid:132) public (cid:132)(cid:132) public
getLength()(): : trảtrả vềvề chiều getPort()(): : trảtrả vềvề sốsố hiệuhiệu port
29
g n ũ D n ấ T õ V
:
V G
PHẦN 3 P TRÌNH LLẬẬP TRÌNH LẬP TRÌNH TCP Socket TCP Socket TCP Socket
g n ũ D n ấ T õ V
:
V G
MôMô hìnhhình truyền
tin Socket truyền tin Socket
31
g n ũ D n ấ T õ V
:
V G
QuyQuy trình
Client trình phíaphía Client
Các bước cài đặt chương trình phía Client bằng Java: (cid:132) Bước 1:Tạo một đối tượng Socket – Socket client =new Socket(“hostname”,portName);
tin tới Socket – PrintWriter out=new PrintWriter(client.getOutputStream(),true);
(cid:132) Bước 2:Tạo một luồng xuất để có thể sử dụng để gửi thông
server – BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream())); (cid:132) Bước 4:Thực hiện các thao tác vào/ra với các luồng nhập
và luồng xuất – Đối với các luồng xuất, PrintWriter, ta sử dụng các phương thức print và println, tương tự như
System.out.println.
– Đối với luồng nhập, BufferedReader, ta có thể sử dụng phương thức read() để đọc một ký tự,
hoặc một mảng các ký tự, hoặc gọi phương thức readLine() để đọc vào một dòng ký tự. Cần chú ý rằng phương thức readLine() trả về null nếu kết thúc luồng.
(cid:132) Bước 3:Tạo một luồng nhập để đọc thông tin đáp ứng từ
g n ũ D n ấ T õ V
:
V G
(cid:132) Bước 5: Đóng socket khi hoàn thành quá trình truyền tin 32
VD: VD: QuyQuy trình
Client trình phíaphía Client
VíVí dụdụ: : ViếtViết chchươươngng trình trình client client liênliên kếtkết vớivới mộtmột server. server. NgNgưườiời sửsử dụng dụng nhập nhập vàovào
main(String[] [] argsargs) )
localhost";";
server. dòng kýký tựtự từtừ bànbàn phímphím vàvà gửigửi dữdữ liệuliệu chocho server. mộtmột dòng import java.net java.net.*;.*; import java.io.*;.*; import java.io import public class EchoClient1 public class EchoClient1 public static void main(String {{ public static void String hostname="localhost {{ String hostname=" if(args.length>0)>0) if(args.length {{
hostname=args[0]; hostname=args[0];
}} =null; PrintWriter pwpw=null; PrintWriter =null; BufferedReader brbr=null; BufferedReader try{ try{
Socket s=new Socket(hostname,2007); Socket s=new Socket(hostname,2007); brbr=new
33
g n ũ D n ấ T õ V
:
V G
BufferedReader(newInputStreamReader =new BufferedReader(newInputStreamReader ())); s.getInputStream())); ((s.getInputStream
VD: VD: QuyQuy trình
Client trình phíaphía Client
BufferedReader user=new BufferedReader
user=new BufferedReader BufferedReader InputStreamReader(System.in));));
=new PrintWriter(s.getOutputStream
(new InputStreamReader(System.in (new ()); PrintWriter(s.getOutputStream()); server..."); duoc voivoi server...");
pwpw=new System.out.println("Da ketket noinoi duoc System.out.println("Da while(true)) while(true {{
user.readLine();();
String stst==user.readLine String if(st.equals("exit"))")) if(st.equals("exit {{
break; break;
}} pw.println(st);); pw.println(st pw.flush();(); pw.flush ()); System.out.println(br.readLine()); System.out.println(br.readLine
}}
34
g n ũ D n ấ T õ V
:
V G
}}
VD: VD: QuyQuy trình
Client trình phíaphía Client
catch(IOException e)e) catch(IOException {{
System.err.println(e);); System.err.println(e
}} finally{ finally{
try{ try{
null)br.close();(); if(br!=!=null)br.close if(br null)pw.close();(); if(pwif(pw!=!=null)pw.close
}} catch(IOException e)e) catch(IOException {{
System.err.println(e);); System.err.println(e
}}
}}
}}
35
g n ũ D n ấ T õ V
:
V G
}}
QuyQuy trình
ServerSocket ssss=new
–– ServerSocket
Java: Server bằngbằng Java:
Server trình phíaphía Server trình Server CácCác bbưướcớc đđểể càicài đđặtặt chchươươngng trình ServerSocket (cid:132)(cid:132) BBưướcớc 1: 1: TạoTạo mộtmột đđốiối ttưượngợng ServerSocket =new ServerSocket(port ServerSocket(port)) Socket bằng
(cid:132)(cid:132) BBưướcớc 2: 2: TạoTạo mộtmột đđốiối ttưượngợng Socket
bằng cáchcách chấp chấp nhận nhận liênliên kếtkết từtừ yêuyêu cầucầu
client. SauSau khikhi chấp chấp nhận nhận liênliên kếtkết, , phphươươngng thức thức accept() accept() trảtrả vềvề đđốiối
liênliên kếtkết củacủa client. ttưượngợng Socket
Server. Client vàvà Server. doSomething(s); }); } ss.accept(); (); doSomething(s
chúng tata nênnên giaogiao công
công việcviệc xửxử lýlý đđốiối ttưượngợng s s chocho mộtmột
tuyến đđoạnoạn nàonào đđóó.. tuyến
Socket thểthể hiệnhiện liênliên kếtkết giữagiữa Client while(condion) {) { Socket s= Socket s=ss.accept while(condion rằng chúng khuyến cáocáo rằng –– NgNgưườiời tata khuyến
(cid:132)(cid:132) BBưướcớc 3: 3: TạoTạo mộtmột luồng –– BufferedReader
client nhập đđểể đđọcọc dữdữ liệuliệu từtừ client
(cid:132)(cid:132) BBưướcớc 4: 4: TạoTạo mộtmột luồng
luồng nhập BufferedReader(new in=new BufferedReader(new
BufferedReader in=new InputStreamReader(s.getInputStream())); ())); InputStreamReader(s.getInputStream xuất đđểể gửigửi dữdữ liệuliệu trởtrở lại luồng xuất =new PrintWriter(s.getOutputStream(),true
PrintWriter(s.getOutputStream(),true););
true đưđượcợc sửsử dụng
dụng đđểể xácxác đđịnhịnh rằng
rằng luồng
luồng sẽsẽ đưđượcợc tựtự đđộngộng đđẩyẩy
server lại chocho server
PrintWriter pwpw=new –– PrintWriter Trong đđóó thamtham sốsố true –– Trong rara.. (cid:132)(cid:132) BBưướcớc 5: 5: Thực (cid:132)(cid:132) BBưướcớc 6: 6: ĐĐóngóng socket s
Thực hiệnhiện cáccác thao thao táctác vàovào rara vớivới cáccác luồng nhập vàvà luồng
socket s khikhi đãđã truyền truyền tin tin xong luồng nhập xong. . ViệcViệc đđóngóng socket xuất luồng xuất cũng đđồngồng socket cũng
36
g n ũ D n ấ T õ V
:
V G
nghĩa vớivới việcviệc đđóngóng cáccác luồng nghĩa luồng. .
VD: VD: QuyQuy trình
Server trình phíaphía Server
VíVí dụdụ: : ViếtViết chchươươngng trình
trình server
server EchoServer
EchoServer đđểể phục
trình phục vụvụ chchươươngng trình
EchoClient EchoClient
import java.net java.net.*;.*; import java.io.*;.*; import java.io import public class EchoServer1 public class EchoServer1 {{
DEFAULT_PORT=2007; int DEFAULT_PORT=2007; main(String[] [] argsargs) )
public final static int public final static public static void main(String public static void port=DEFAULT_PORT; int port=DEFAULT_PORT; { { int try{ try{
=new ServerSocket(port
ServerSocket(port););
ServerSocket ssss=new ServerSocket Socket s=null; Socket s=null;
37
g n ũ D n ấ T õ V
:
V G
VD: VD: QuyQuy trình
Server trình phíaphía Server while(true)) while(true {{ try{ try{
ss.accept();();
s=s=ss.accept PrintWriter pwpw=new PrintWriter
PrintWriter(new =new PrintWriter(new ())); OutputStreamWriter(s.getOutputStream())); OutputStreamWriter(s.getOutputStream
BufferedReader brbr=new BufferedReader
BufferedReader(new =new BufferedReader(new ())); InputStreamReader(s.getInputStream())); InputStreamReader(s.getInputStream
while(true){){ while(true
line.toUpperCase();();
br.readLine();(); String line=br.readLine String line= if(line.equals("exit"))break;; if(line.equals("exit"))break String upper=line.toUpperCase String upper= pw.println(upper);); pw.println(upper pw.flush();(); pw.flush
}//while }//while
} //try } //try
38
g n ũ D n ấ T õ V
:
V G
VD: VD: QuyQuy trình
Server trình phíaphía Server
catch(IOException e)e) catch(IOException {{ } finally{ } finally{
try{ try{ !=null){ if(sif(s!=null){
s.close();(); s.close
}} catch(IOException e){}e){} }}catch(IOException
}}
}}
}} e) { } catch(IOException e) { } catch(IOException
}}
trình trêntrên làlà chchươươngng trình client/server đơđơnn tuyến }} NhậnNhận xétxét:: ChChươươngng trình
tuyến (single thread) thời đđiểmiểm. .
trình client/server quản lýlý đưđượcợc mộtmột liênliên kếtkết tại nhiều liênliên kếtkết cùng quản lýlý nhiều tuyến. . CácCác tại mộtmột thời cùng mộtmột lúclúc. . ĐĐểể
39
(single thread) chỉchỉ quản phải quản server cócó thểthể phải nhận cáccác liênliên kếtkết vàvà chuyển chấp nhận server chấp chuyển cáccác liênliên kếtkết nàynày chocho
g n ũ D n ấ T õ V
:
V G
server đơđơnn tuyến server thực tếtế mộtmột server Trong thực Trong thực hiệnhiện đđiềuiều nàynày server thực (thread) xửxử lýlý.. tuyến (thread) từng tuyến từng
SửSử dụng
dụng đđaa tuyến
(multithread) tuyến (multithread)
(cid:132)(cid:132) CácCác server
tại mộtmột thời
quản lýlý đưđượcợc mộtmột client
thời đđiểmiểm. . KhiKhi
client tại server cầncần xửxử lýlý mộtmột yêuyêu cầucầu công việcviệc màmà server
thời không biếtbiết trtrưướcớc đưđượcợc thời
hoàn thành
công việcviệc xửxử lýlý thì
thì cáccác server
server nàynày làlà
client làlà quáquá lớnlớn vàvà không thành công chấp nhận
nhận đưđượcợc..
phục đđiềuiều nàynày, , ngngưườiời tata quản
server nhnhưư đãđã viếtviết ở ở trêntrên rấtrất đơđơnn giảngiản nhnhưưngng nhnhưượcợc đđiểmiểm củacủa nónó làlà bịbị hạnhạn chếchế vềvề mặtmặt hiệuhiệu nnăăngng vìvì nónó chỉchỉ quản khối llưượngợng công khối củacủa client đđiểmiểm hoàn không thểthể chấp không khắc phục (cid:132)(cid:132) ĐĐểể khắc client bằng
. Server nàynày
tuyến (thread) nhiều client server ttươươngng tranh
thread đđểể quản
quản lýlý từng
bằng mộtmột tuyến củacủa client server làmlàm việcviệc vớivới nhiều server đưđượcợc gọigọi làlà server server tạotạo rara mộtmột thread server mộtmột client,
client, sausau đđóó tiếptiếp tụctục lắng
nghe cáccác client
lắng nghe
phiên quản lýlý mỗimỗi phiên phép cáccác riêng, , chocho phép (thread) riêng thời. Server client đđồngồng thời (concurrent server)-- tranh (concurrent server) từng yêuyêu cầucầu từtừ khác.. client khác 40
g n ũ D n ấ T õ V
:
V G
VD VD vềvề sửsử dụng
tuyến dụng đđaa tuyến
(cid:132)(cid:132) Trong
chúng tata sẽsẽ xemxem xétxét cáchcách trình client/server
client/server đđaa
Trong phần tiếntiến hành tuyến (multi tuyến
phần ddưướiới đâđâyy chúng hành càicài đđặtặt chchươươngng trình thread). (multi--thread).
41
g n ũ D n ấ T õ V
:
V G
VD VD vềvề sửsử dụng
dụng đđaa tuyến
Server) tuyến ((phíaphía Server)
.*; import java.net
IOException (Socket s) throws IOException
BufferedReader(new InputStreamReader(socket.getInputStream ())); InputStreamReader(socket.getInputStream()));
import java.io java.io.*; import java.net.*;.*; import class EchoServe extends Thread EchoServe extends Thread class socket;; { private Socket socket { private Socket in; BufferedReader in; private BufferedReader private PrintWriter out;out; private PrintWriter private EchoServe (Socket s) throws public EchoServe public { socket = s; { socket = s; : "+socket); System.out.println("Serving: "+socket); System.out.println("Serving in = new BufferedReader(new in = new flush: phép autoauto--flush: // // ChoCho phép out = new PrintWriter(new out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(( BufferedWriter(new OutputStreamWriter
())), true); socket.getOutputStream())), true); socket.getOutputStream
ngoại lệlệ
lời gọigọi nàonào ở ở trêntrên đưđưaa rara ngoại trình gọigọi cócó trách trách nhiệmnhiệm đđóngóng socket. socket. NgNgưượcợc lại lại tuyến tuyến đđoạnoạn sẽsẽ
// // NếuNếu bấtbất kỳkỳ lời thì chchươươngng trình // // thì socket // // sẽsẽ đđóngóng socket start(); start();
42
g n ũ D n ấ T õ V
:
V G
}}
VD VD vềvề sửsử dụng
dụng đđaa tuyến
Server) tuyến ((phíaphía Server)
public void run() public void run() {{
try { while (true) { try { while (true) {
in.readLine();();
str.toUpperCase();();
with.."+socket););
("....Server is waiting..."); System.out.println("....Server is waiting..."); System.out.println String strstr = = in.readLine String ”) ) break; str.equals(“exit”) ) break; if (if (str.equals(“exit : " + strstr);); System.out.println("Received: " + System.out.println("Received : "+ socket); System.out.println("From: "+ socket); System.out.println("From String upper=str.toUpperCase String upper= client lại chocho client // // gửigửi lại out.println(upper);); out.println(upper }//while }//while System.out.println("Disconnected with.."+socket System.out.println("Disconnected catch (IOException
e) { } IOException e) { }
}} catch ( finally finally { try { try
socket.close(); } { { socket.close (); } e) { } catch(IOException e) { } catch(IOException
}}
}}
43
g n ũ D n ấ T õ V
}}
:
V G
VD VD vềvề sửsử dụng
dụng đđaa tuyến
Server) tuyến ((phíaphía Server)
public class TCPServer1 public class TCPServer1 { {
main(String[] [] argsargs) throws IOException ) throws IOException
PORT=0; . int PORT=0; . static int static public static void main(String public static void {{
== 1) args.length == 1)
if (if (args.length {{
PORT=Integer.parseInt(args[0]); // NhậpNhập sốsố hiệuhiệu cổng PORT=Integer.parseInt(args[0]); // cổng từtừ đđốiối dòng lệnh dòng lệnh
}}
ServerSocket(PORT););
44
g n ũ D n ấ T õ V
:
V G
// // TạoTạo mộtmột đđốiối ttưượngợng Server Socket Server Socket s = new ServerSocket(PORT ServerSocket s = new ServerSocket addrs= = InetAddress.getLocalHost InetAddress addrs InetAddress System.out.println("TCP/Server running on : "+ System.out.println("TCP (); InetAddress.getLocalHost(); addrs +" ,+" ,Port"+s.getLocalPort /Server running on : "+ addrs ()); Port"+s.getLocalPort());
VD VD vềvề sửsử dụng
dụng đđaa tuyến
Server) tuyến ((phíaphía Server)
try try {{
while(true) ) while(true {{
Phong tỏatỏa chocho tới
tuyến đđoạnoạn quản
quản lýlý riêng
riêng từng
từng liênliên kếtkết
tới khikhi cócó mộtmột liênliên kếtkết đđếnến s.accept();(); socket = = s.accept
// // Phong Socket socket Socket try try { new EchoServe(socket { new } } catch(IOException EchoServe(socket); ); // // TạoTạo mộtmột tuyến (); } socket.close(); } catch(IOException e) { e) { socket.close
}}
} finally { s.close } finally { (); } s.close(); }
} }
45
g n ũ D n ấ T õ V
:
V G
}}
VD VD vềvề sửsử dụng
dụng đđaa tuyến
Client) tuyến ((phíaphía Client)
java.io.*;.*;
.*; import java.io
IOException ) throws IOException
java.net.*; import import java.net import public class TCPClient1 public class TCPClient1 main(String[] [] argsargs) throws { public static void main(String { public static void != 2) args.length != 2) { if (args.length { if ( {{
dụng: java
: java TCPClient
TCPClient hostid
port#"); hostid port#");
System.out.println("Sử dụng System.out.println("Sử System.exit(0); System.exit(0);
}} try try { {
= InetAddress.getByName(args[0]); addr = InetAddress.getByName(args[0]);
socket = new
= new Socket(addr
, Integer.parseInt(args[1])); Socket(addr, Integer.parseInt(args[1]));
InetAddress addr InetAddress Socket socket Socket try try = " + socket); { { System.out.println("socket System.out.println("socket = " + socket); BufferedReader(( in = new BufferedReader BufferedReader in = new BufferedReader
new InputStreamReader(socket.getInputStream new
())); InputStreamReader(socket.getInputStream()));
// Output is automatically flushed by PrintWriter PrintWriter:: // Output is automatically flushed by PrintWriter out =new out =new PrintWriter(new BufferedWriter(( PrintWriter(new BufferedWriter PrintWriter new OutputStreamWriter(socket.getOutputStream())),true new
OutputStreamWriter(socket.getOutputStream())),true););
46
g n ũ D n ấ T õ V
:
V G
VD VD vềvề sửsử dụng
dụng đđaa tuyến
Client) tuyến ((phíaphía Client)
// // ĐĐọcọc dòng
myinput = new
= new DataInputStream(new
DataInputStream(new BufferedInputStream(System.in
BufferedInputStream(System.in));));
dòng kýký tựtự từtừ bànbàn phímphím DataInputStream myinput DataInputStream try try { for(;;) { for(;;) {{
anything followed by RETURN, System.out.println("Type anything followed by RETURN, System.out.println("Type or Exit to terminate the program."); or Exit to terminate the program.");
(); myinput.readLine();
(); // Recive
it back Recive it back
strout = = in.readLine strin.length()==()==strout.length
String strinstrin==myinput.readLine String // Quit if the user typed ctrl+D ctrl+D // Quit if the user typed ")) break; strin.equals("exit")) break; if (if (strin.equals("exit else else ); // Send the message out.println(strin); // Send the message out.println(strin in.readLine(); // String strout String strout.length())()) if ( strin.length if ( { // Compare Both Strings { // Compare Both Strings
System.out.println("Received: "+: "+strout System.out.println("Received
strout););
} } else else
System.out.println("Echo bad System.out.println("Echo
bad ---- string unequal"+
string unequal"+ strout
strout););
} // of for ;; } // of for ;;
47
g n ũ D n ấ T õ V
:
V G
VD VD vềvề sửsử dụng
dụng đđaa tuyến
Client) tuyến ((phíaphía Client)
} catch (IOException } catch (
IOException e)e) e.printStackTrace();(); { { e.printStackTrace }} // User is exiting // User is exiting } finally } finally {{
...exit"); System.out.println("EOF...exit"); System.out.println("EOF socket.close();(); socket.close
}}
} } catch(UnknownHostException e)e) catch(UnknownHostException find host"); System.err.println("Can't find host"); {{ System.err.println("Can't System.exit(1); System.exit(1);
} } catch (SocketException catch ( {{
SocketException e)e) open socket"); System.err.println("Can't open socket"); System.err.println("Can't e.printStackTrace();(); e.printStackTrace System.exit(1); System.exit(1);
}}
} }
48
g n ũ D n ấ T õ V
}}
:
V G
PHẦN 4 P TRÌNH LLẬẬP TRÌNH LẬP TRÌNH UDP Socket UDP Socket UDP Socket
g n ũ D n ấ T õ V
:
V G
LậpLập trình
UDP Socket trình UDP Socket
Java cầncần cócó haihai lớplớp
dụng UDP UDP trong
trong Java DatagramSocket.. DatagramPacket vàvà DatagramSocket
datagram vàvà chocho phép
byte dữdữ liệuliệu vàovào cáccác phép tata mởmở
nhận đưđượcợc..
thời thực
(cid:132)(cid:132) ViệcViệc càicài đđặtặt ứngứng dụng làlà DatagramPacket DatagramPacket đđóngóng góigói cáccác byte (cid:132)(cid:132) DatagramPacket tin UDP đưđượcợc gọigọi làlà datagram góigói tin UDP datagram khikhi nhận cáccác datagram DatagramSocket đđồngồng thời (cid:132)(cid:132) MộtMột DatagramSocket nhận vàvà gửigửi góigói tin.
thực hiệnhiện cảcả haihai tin. ĐĐểể gửigửi dữdữ liệuliệu, , tata đđặtặt dữdữ
bằng tin bằng
trong mộtmột DatagramPacket dụng DatagramSocket
nhận dữdữ liệuliệu, , tata
DatagramPacket vàvà gửigửi góigói tin DatagramSocket. . ĐĐểể nhận DatagramPacket từtừ
nhiệmnhiệm vụvụ nhận liệuliệu trong cáchcách sửsử dụng nhận mộtmột đđốiối ttưượngợng DatagramPacket nhận DatagramSocket vàvà sausau đđóó đđọcọc nộinội dung DatagramSocket
tin. dung củacủa góigói tin.
50
g n ũ D n ấ T õ V
:
V G
LậpLập trình
(cid:132)(cid:132) UDP UDP không
UDP Socket trình UDP Socket không cócó bấtbất kỳkỳ khái host. MộtMột socket
socket gửigửi tất
tới mộtmột
khái niệmniệm nàonào vềvề liênliên kếtkết tất cảcả dữdữ liệuliệu tới cổng màmà
tất cảcả dữdữ liệuliệu từtừ mộtmột cổng
giữagiữa haihai host. cổng hoặc hoặc nhận cổng không cầncần quan không
nhận tất quan tâmtâm host
host nàonào gửigửi..
DatagramSocket cócó thểthể gửigửi dữdữ liệuliệu tới
hoặc nhận
DatagramSocket không
nhận dữdữ liệuliệu từtừ nhiều dành riêng
tới nhiều nhiều host đđộcộc nhiều host riêng chocho mộtmột
không dành
thức trong giaogiao thức
(cid:132)(cid:132) MộtMột DatagramSocket host đđộcộc lậplập hoặc host lậplập. . DatagramSocket liênliên kếtkết cụcụ thểthể thểthể nàonào cảcả nhnhưư trong TCP. TCP.
51
g n ũ D n ấ T õ V
:
V G
LậpLập trình
UDP Socket trình UDP Socket
(cid:132)(cid:132) CácCác socket TCP
socket TCP xemxem liênliên kếtkết mạngmạng nhnhưư làlà mộtmột
luồng xuất
xuất nhận
nhận dữdữ liệuliệu vớivới cáccác luồng nhận đưđượcợc từtừ socket. UDP
nhập luồng nhập không socket. UDP không từng góigói datagram đưđượcợc
phải làmlàm việcviệc vớivới từng trong datagram
luồng: : tata gửigửi vàvà nhận luồng vàvà luồng phép đđiềuiều nàynày; ; tata phải chocho phép tin. TấtTất cảcả dữdữ liệuliệu đưđượcợc đđặtặt trong tin. gửigửi đđii ddưướiới dạng
tin. dạng mộtmột góigói tin.
tin nàynày cũng
nhận đưđượcợc bởibởi mộtmột nhómnhóm
tin không
quan đđếnến góigói tin
tin tiếptiếp theo
cũng cócó thểthể nhận cũng cócó thểthể bịbị mấtmất. . MộtMột góigói tin phải liênliên quan tin, không
nhất không nhất theo. . ChoCho trtrưướcớc tin không cócó cáchcách nàonào đđểể biếtbiết đưđượcợc góigói tin
(cid:132)(cid:132) GóiGói tin hoặc cũng hoặc thiết phải thiết haihai góigói tin, nàonào đưđượcợc gửigửi trtrưướcớc vàvà góigói tin
tin nàonào đưđượcợc gửigửi sausau..
52
g n ũ D n ấ T õ V
:
V G
tin UDP NhậnNhận cáccác góigói tin UDP (cid:132)(cid:132) TrTrưướcớc khikhi mộtmột ứngứng dụng
tin UDP đưđượcợc
cổng socket vớivới mộtmột cổng
dụng DatagramSocket
dụng cócó thểthể đđọcọc cáccác góigói tin UDP phải gángán mộtmột socket DatagramSocket, , vàvà tạotạo rara mộtmột chứa chocho
gửigửi bởibởi cáccác máymáy ở ở xaxa, , nónó phải bằng cáchcách sửsử dụng UDP UDP bằng DatagramPacket sẽsẽ đđóngóng vaivai tròtrò nhnhưư làlà mộtmột bộbộ chứa DatagramPacket tin UDP. dữdữ liệuliệu củacủa góigói tin UDP.
53
g n ũ D n ấ T õ V
:
V G
tin UDP NhậnNhận cáccác góigói tin UDP dụng muốnmuốn đđọcọc cáccác góigói tin UDP,
(cid:132)(cid:132) KhiKhi mộtmột ứngứng dụng
tin UDP, nónó gọigọi phphươươngng thức thức thức nàynày saosao chép
chép góigói tin UDP
DatagramSocket.receive(), (), phphươươngng thức DatagramSocket.receive DatagramPacket. . XửXử lýlý nộinội dung mộtmột DatagramPacket
dung nóinói tin
tin vàvà tiếntiến trình
trình lặplặp lại
tin UDP vàovào lại khikhi cầncần..
byte[256],256); DatagramPacket(new byte[256],256);
=new DatagramPacket(new DatagramPacket dpdp=new DatagramPacket =new DatagramSocket(2000); DatagramSocket dsds=new DatagramSocket(2000); DatagramSocket finished=false; boolean finished=false; boolean while(!finished)) while(!finished {{
ds.receive(dp);); ds.receive(dp ////XửXử lýlý góigói tintin
}} ds.close();(); ds.close
54
g n ũ D n ấ T õ V
:
V G
tin UDP NhậnNhận cáccác góigói tin UDP
tin ứngứng dụng
phải làmlàm việcviệc trực
dụng phải nhiên nếunếu ứngứng dụng
byte. TuyTuy nhiên
dụng làlà đđọcọc vvăănn bảnbản thì
trực tiếptiếp vớivới mộtmột thì tata chuyển đđổiổi giữagiữa
byte vàvà luồng
luồng stream
nhập ByteArrayInputStream
(cid:132)(cid:132) KhiKhi xửxử lýlý góigói tin mảngmảng byte. cócó thểthể sửsử dụng mảngmảng byte
dung củacủa mộtmột datagram
dụng cáccác lớplớp từtừ góigói vàovào rara đđểể chuyển reader. stream vàvà reader. ByteArrayInputStream vớivới luồng nhập datagram vàvà sausau đđóó kếtkết nốinối vớivới mộtmột kiểukiểu dung củacủa góigói xuất tới
tới nộinội dung
khác, , khikhi đđóó bạnbạn cócó thểthể truytruy xuất
nộinội dung luồng khác luồng dàng.. UDP UDP mộtmột cáchcách dễdễ dàng nhiều ngngưườiời lậplập trình
(cid:132)(cid:132) BằngBằng cáchcách gắngắn kếtkết luồng
I/O luồng vàovào rara I/O
thích dùng trình thích bằng cáchcách sửsử dụng hoặc BufferedReader
dùng cáccác luồng luồng dụng luồng BufferedReader đđểể truytruy xuất
xuất tới
tới nộinội
đđểể xửxử lýlý dữdữ liệuliệu, , bằng DataInputStream hoặc DataInputStream byte. dung củacủa cáccác mảngmảng byte. dung
55
g n ũ D n ấ T õ V
:
V G
(cid:132)(cid:132) RấtRất nhiều
tin UDP NhậnNhận cáccác góigói tin UDP
56
g n ũ D n ấ T õ V
:
V G
tin UDP GởiGởi cáccác góigói tin UDP
(cid:132)(cid:132) LớpLớp DatagramSocket DatagramSocket cũng dụng phải
dụng đđểể gửigửi cáccác góigói tin.
cũng đưđượcợc sửsử dụng phải tạotạo rara mộtmột DatagramPacket thiết lậplập đđịaịa chỉchỉ vàvà thông tin, tin. KhiKhi gửigửi góigói tin, cổng, , tin cổng thông tin
(cid:132)(cid:132) NếuNếu muốnmuốn gửigửi thông
ứngứng dụng vàvà ghighi dữdữ liệuliệu cầncần truyền thông tin cổng cũng đãđã biếtbiết đđịaịa chỉchỉ vàvà sốsố hiệuhiệu cổng
tin nhận sàng đđểể gửigửi, , tata sửsử dụng thức dụng phphươươngng thức
57
g n ũ D n ấ T õ V
:
V G
DatagramPacket, , thiết byte. truyền vàovào mảngmảng byte. thì tata cũng phúc đđápáp thì tin phúc tin sẵnsẵn sàng nhận đưđượcợc. . MỗiMỗi khikhi góigói tin DatagramSocket đđểể gửigửi góigói tin củacủa góigói tin send() củacủa lớplớp DatagramSocket send() tin đđii..
tin UDP GởiGởi cáccác góigói tin UDP
lắng nghe 2000 cổng 2000 nghe cáccác góigói tin
(new byte[256], 256); DatagramPacket (new byte[256], 256);
InetAddress.getByName ( ( somehost somehost ) );) );
//Socket lắng tin đđếnến trêntrên cổng //Socket socket = new DatagramSocket(2000); DatagramSocket socket = new DatagramSocket(2000); DatagramSocket packet = new DatagramPacket DatagramPacket packet = new DatagramPacket packet.setAddress ( ( InetAddress.getByName packet.setAddress packet.setPort ( 2000 ); ( 2000 ); packet.setPort finished = false; boolean finished = false; boolean while (!finished ) while (!finished ) {{
buffer vùng đđệmệm buffer
chẳng hạnhạn nhnhưư đđọcọc góigói tin tin kháci kháci hoặc hoặc kiểmkiểm tratra
tin nàonào cầncần gửigửi đđii hay hay không không
// // GhiGhi dữdữ liệuliệu vàovào vùng ......... ......... (packet); socket.send (packet); socket.send // // Thực hành đđộngộng nàonào đđóó, , chẳng Thực hiệnhiện hành xemor xemor // // còncòn góigói tin ......... .........
58
g n ũ D n ấ T õ V
:
V G
}} socket.close();(); socket.close
VíVí dụdụ minhminh họahọa giaogiao thức ĐĐểể minhminh họahọa cáccác góigói tin UDP
nhận nhnhưư thếthế nàonào, , dụng sausau. . ViếtViết
theo mômô hìnhhình Client/Server thực hiệnhiện cáccác thao
trình theo Client thực
thức UDPUDP tin UDP đưđượcợc gửigửi vàvà nhận chạy ứngứng dụng Client/Server đđểể:: thao táctác sausau đâđâyy:: dùng nhập
chúng tata sẽsẽ viếtviết, , biênbiên dịchdịch vàvà chạy chúng chchươươngng trình CLIENT: Client CLIENT: (cid:132)(cid:132) Client
nhập từtừ bànbàn phímphím
phản hồihồi trởtrở lại
lại từtừ Server
thị Server vàvà hiểnhiển thị
nhận thông tin phản thông tin tin đđóó trêntrên mànmàn hìnhhình
thực hiệnhiện cáccác thao
thao táctác sausau::
do client gửigửi tới
tới vàvà in thành chữchữ hoahoa vàvà gửigửi trởtrở lại
in lênlên mànmàn hìnhhình lại chocho
Client gửigửi mộtmột xâuxâu kýký tựtự do do ngngưườiời dùng server chocho server Client nhận (cid:132)(cid:132) Client thông tin thông Server thực SERVER: Server SERVER: nhận xâuxâu kýký tựtự do client Server nhận (cid:132)(cid:132) Server Server biếnbiến đđổiổi xâuxâu kýký tựtự thành (cid:132)(cid:132) Server Client Client
59
g n ũ D n ấ T õ V
:
V G
VíVí dụdụ minhminh họahọa giaogiao thức
UDP (CLIENT) thức UDP (CLIENT)
CONG_MAC_DINH=9; int CONG_MAC_DINH=9; main(String argsargs[])[])
import java.net java.net.*;.*; import java.io.*;.*; import java.io import UDPClient public class UDPClient public class public final static int { { public final static public static void main(String public static void {{
String hostname; String hostname; port=CONG_MAC_DINH; int port=CONG_MAC_DINH; int if(args.length>0)>0) if(args.length {{
hostname=args[0]; hostname=args[0]; try{ try{ }} catch(Exception e){e){ catch(Exception
port =Integer.parseInt(args[1]); port =Integer.parseInt(args[1]);
}}
60
g n ũ D n ấ T õ V
:
hostname="127.0.0.1"; hostname="127.0.0.1";
V G
}} elseelse {{ }}
VíVí dụdụ minhminh họahọa giaogiao thức
UDP (CLIENT) thức UDP (CLIENT)
try{ try{
InetAddress.getByName(hostname);); BufferedReader =new BufferedReader userInput=new InputStreamReader(System.in));)); =new DatagramSocket(port
DatagramSocket(port););
InetAddress dc=dc=InetAddress.getByName(hostname InetAddress BufferedReader userInput BufferedReader (new InputStreamReader(System.in (new DatagramSocket dsds =new DatagramSocket while(true){){ while(true
userInput.readLine();();
String line=userInput.readLine String line= if(line.equals("exit"))break;; if(line.equals("exit"))break line.getBytes();(); byte[] data=line.getBytes byte[] data= DatagramPacket dpdp=new DatagramPacket
DatagramPacket =new DatagramPacket
data,data.length,dc,port);); ((data,data.length,dc,port
ds.send(dp);); ds.send(dp dp.setLength(65507); dp.setLength(65507); ds.receive(dp);); ds.receive(dp =new ByteArrayInputStream bisbis =new ByteArrayInputStream ()); ByteArrayInputStream(dp.getData()); ByteArrayInputStream(dp.getData BufferedReader(new =new BufferedReader(new BufferedReader disdis =new BufferedReader InputStreamReader(bis));)); InputStreamReader(bis ()); System.out.println(dis.readLine()); System.out.println(dis.readLine
}}
61
}}
g n ũ D n ấ T õ V
:
V G
VíVí dụdụ minhminh họahọa giaogiao thức
UDP (CLIENT) thức UDP (CLIENT)
catch(UnknownHostException e)e) catch(UnknownHostException {{
System.err.println(e);); System.err.println(e
}} catch(IOException e)e) catch(IOException {{
System.err.println(e);); System.err.println(e
}}
}}
62
g n ũ D n ấ T õ V
:
V G
VíVí dụdụ minhminh họahọa giaogiao thức
UDP (SERVER) thức UDP (SERVER)
UDPServer public class UDPServer public class { {
public final static int public final static CONG_MAC_DINH=9; int CONG_MAC_DINH=9;
main(String argsargs[])[])
public static void main(String public static void {{
port=CONG_MAC_DINH; int port=CONG_MAC_DINH; int
try{ try{ }} catch(Exception e){e){ catch(Exception
port =Integer.parseInt(args[1]); port =Integer.parseInt(args[1]);
63
g n ũ D n ấ T õ V
:
V G
}}
VíVí dụdụ minhminh họahọa giaogiao thức
UDP (SERVER) thức UDP (SERVER)
try{ try{
=new DatagramSocket(port =new DatagramPacket(new
DatagramSocket(port);); byte[65507],65507); DatagramPacket(new byte[65507],65507);
DatagramSocket dsds =new DatagramSocket DatagramPacket dpdp=new DatagramPacket while(true){){ while(true
BufferedReader disdis =new BufferedReader
ds.receive(dp);); ds.receive(dp =new ByteArrayInputStream bisbis =new ByteArrayInputStream ByteArrayInputStream(dp.getData()); ()); ByteArrayInputStream(dp.getData BufferedReader(new =new BufferedReader(new InputStreamReader(bis));)); InputStreamReader(bis
dis.readLine();();
String s=dis.readLine String s= System.out.println(s);); System.out.println(s s.toUpperCase();(); s.toUpperCase dp.setData(s.getBytes()); ()); dp.setData(s.getBytes ()); dp.setLength(s.length()); dp.setLength(s.length ()); dp.setAddress(dp.getAddress()); dp.setAddress(dp.getAddress ()); dp.setPort(dp.getPort()); dp.setPort(dp.getPort ds.send(dp);); ds.send(dp
}}
64
}}
g n ũ D n ấ T õ V
:
V G
VíVí dụdụ minhminh họahọa giaogiao thức
UDP (SERVER) thức UDP (SERVER)
catch(UnknownHostException e)e) catch(UnknownHostException {{
System.err.println(e);); System.err.println(e
}} catch(IOException e)e) catch(IOException {{
System.err.println(e);); System.err.println(e
}}
}}
65
g n ũ D n ấ T õ V
:
V G
}}
HẾT BÀI 2BBÀÀI 2I 2
g n ũ D n ấ T õ V
:
V G