黑马程序员_Java_网络编程
2015-03-08 11:46
239 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
一、概述
1、 网络模型
OSI参考模型、TCP/IP参考模型
![](http://img.blog.csdn.net/20150308114516010)
网际层常用的协议是TCP或UDP;传输层使用的协议是IP;应用层使用的是HTTP和FTP协议。
2、 网络框架:
(1)C/S:Client/Server,客户端/服务端。
特点:需要在客户端和服务端都需要安装编写的软件,维护较麻烦。
好处:可以减轻服务端的压力。
(2)B/S:Browser/Server,浏览器/服务端。
特点:客户端不用单独编写软件。因为客户端用的就是浏览器。对于软件升级,只需考虑服务端即可。
弊端:所有的程序都运行在服务端,客户端的浏览器毕竟解析能力较弱。
3、 网络通信三要素:
IP地址、端口号、传输协议(通用协议TCP/IP)
(1)IP地址
分为A、B、C、D 段。
本地回环地址(默认IP 地址):127.0.0.1(可以用来测试网卡)
主机名:localhost(默认)
(2)端口号:
数字标识,用于标识进程的逻辑地址。
分为物理端口和逻辑端口。一般网络应用程序都有数字进行标识,称呼这个数字为端口,也就是逻辑端口。而且一个网络应用程序对应多个不同的(数字)端口。
有效端口:0~65535,其中0~1024为系统使用或保留端口。
(3)传输协议
常见协议:TCP协议、UDP协议。
4、 计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
5、 各种网络分类方式:
A: 按网络覆盖范围划分
局域网(几米至10 公里以内) 城域网(10~100 公里)
广域网(几百公里到几千公里) 国际互联网
B: 按网络拓扑结构划分
总线型网络 星形网络 环型网络 树状网络 混合型网络
C: 按传输介质划分
有线网 无线网
D: 按网络使用性质划分
公用网 专用网
二、IP地址(InetAddress)
1、 IP地址=网络号码+主机地址。
A 类IP 地址:第一段号码为网络号码,剩下的三段号码为本地计算机的号码
B 类IP 地址:前二段号码为网络号码,剩下的二段号码为本地计算机的号码
C 类IP 地址:前三段号码为网络号码,剩下的一段号码为本地计算机的号码
特殊地址:
127.0.0.1:回环地址,可用于测试本机的网络是否有问题。在命令行窗口输入ping 127.0.0.1。
ipconfig:查看本机IP地址
xxx.xxx.xxx.0网络地址
xxx.xxx.xxx.255广播地址
2、 InetAddress类
(1)无构造函数,封装的是IP地址,可通过getLocalHost()方法获取InetAddress对象,此方法是静态的,返回本类对象。
(2)方法:
1)static InetAddress getLocalHost():返回本地主机。
2)static InetAddress getByName(String host):获取指定主机的IP和主机名。
3)static InetAddress[] getAllByName(String host):在给定主机名的情况下根据系统上配置的名称服务返回IP地址所组成的数组。返回对象不唯一时,用此方法。
4)String getHostAddress():返回IP地址字符串(文本形式)。
5)String getHostName():返回IP地址的主机名。
代码示例:
三、UDP
1、 UDP概述
(1)特点:
a、面向无连接,即将数据及源和目的封装成数据包中,不建立链接的发送
b、每个数据包的大小限制在64K之内
c、因无连接,是不可靠的协议
d、不建立连接,速度快。
(2)弊端:容易丢失数据包。
(3)举例:聊天、视频会议、桌面共享都可以作为UDP传输。UDP相当于步话机。
2、 UDP传输
(1)Socket
Socket:英文译“插座”、”套接字”。
网络编程其实就是Socket 编程。Socket 就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket 间的通信。
数据在两个Socket 间通过IO 传输。
(2)UDP 的Socket 服务如何建立?
1) DatagramSocket 与DatagramPacket
2) 建立发送端、接收端
3) 建立数据包
4)调用Socket 的发送接收方法
5)关闭Socket。
3、 DatagramSocket
(1)DatagramSocket类:用来发送和接收数据报包的套接字。
(2)主要方法:
receive(DatagramPacket p):从此套接字接收数据报包。
send(DatagramPacket p):从此套接字发送数据报包。
4、 DatagramPacket
(1)DatagramPacket类:表示数据报包,用来实现无线接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。
(2)主要方法:
InetAddress getAddress :返回IP地址(对方的)
byte[] getData:返回数据缓冲区
int getLength():返回将要发送或接收到的数据长度
int getPort():返回端口号(对方的)
5、 UDP发送接收代码示例:
6、 编写一个聊天程序
有收数据的部分 、 发数据的部分,这两部分需要同时执行,那就需要用到多线程技术。
代码示例:
四、TCP
1、 TCP概述
(1)特点:
a、面向连接,在建立连接后,形成传输数据的通道
b、在连接中进行大数据量的传输
c、通过三次握手完成连接,是可靠的协议
d、必须建立连接,效率稍慢
(2)TCP是面向连接的,必须连接成功才能传输数据,应用于下载等程序上。三次握手:第一次本方发送请求,第二次对方确认连接,第三次本方再次确认连接成功。
2、 TCP传输
(1)如何建立TCP?
1)Socket 和ServerSocket
2)建立客户端和服务器端
3)建立连接后,通过Socket 中的IO 流进行数据传输
4)关闭Socket。
3、 Socket
(1)Socket类:此类实现客户端套接字。套接字是两套机器间通讯的端点。步骤:创建Socket服务,并指定连接的主机护端口。
(2)构造函数:
Socket():创建空参数的客户端对象,一般用于服务端接收数据
Socket(String host,int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
(3)主要方法:
connect(SocketAddress endpoint,int timeout):将套接字连接到指定服务器,并指定一个超时值。
InetAddress getInetAddress():返回套接字的地址
shutdownInput():将此套接字的输入流置于“流的末尾”
shutdownOutput:禁用此套接字的输出流。
InputStream getInputStream():返回此套接字的输入流,Socket对象调用
OutputStream getOutputStream():返回套接字的输出流,Socket对象调用
4、 ServerSocket
(1)ServerSocket:服务器端。
(2)建立服务器端的步骤:
1)建立服务端的Socket服务,并监听一个端口。
2)获取连接过来的客户对象,通过ServerSocket的accept()方法,此方法是阻塞式的,如果服务端没有连接到就会一直等待
3)客户端如果发过来数据,则服务端要使用对应的客户端对象,并获取到该客户端对象的读取流读取发过来的数据,并输出到指定目的地。
4)关闭服务端(可选)。一般服务端是常开的,因为在实际应用中,随时有客户端在请求连接和服务。但这里需要定时关闭客户端对象流,避免某一个客户端长时间占用服务器端。
(3)构造函数:
ServerSocket():创建非绑定服务器套接字
ServerSocket(int port):创建绑定特定端口的服务器套接字。
ServerSocket(int port,int backlog):利用指定的backlog 创建服务器套接字并将其绑定到指定的本地端口号,backlog 是指能连接到服务器的客户端的同时的最大个数(就是客户端同时在线个数)。
(4)主要方法:
Socket accept():监听并接受到此套接字的连接。
5、 演示客户端和服务端
(1)客户端上传文件到服务端
代码示例:
(2)客户端上传图片给服务端,服务端反馈结果。
代码示例:
五、URL
1、 URL类:代表一个统一资源定位符,它是指向互联网“资源”指针。
2、 构造函数:
URL(Stirng spec):根据String 表示形式创建URL 对象
URL(Stirng protocol , String host , int port , String file):根据指定protocol、host、port 号和file 创建URL 对象。Protocol 代表协议。
3、 主要方法:
String getFile():获取此 URL 的文件名。
String getHost():获取此 URL 的主机名(如果适用)。
String getPath():获取此 URL 的路径部分。
int getPort():获取此 URL 的端口号。
String getProtocol():获取此 URL 的协议名称。
String getQuery():获取此 URL 的查询部。
URLConnection openConnection():返回一个URLConnection 对象,它表示到URL 所引用的远程对象的连接。也就是调用此对象,就会连接URL 主机,返回主机对象。每次调用此连接URL的协议处理程序的openConnection()方法都打开一个新的连接。
InputStream OpenStream():打开此URL 的连接,并返回一个用于从该连接读入的InputStream;相当于openConnection().getInputStream()此语句。
String getConnectionType():返回连接的头字段值。
4、 代码示例:
一、概述
1、 网络模型
OSI参考模型、TCP/IP参考模型
网际层常用的协议是TCP或UDP;传输层使用的协议是IP;应用层使用的是HTTP和FTP协议。
2、 网络框架:
(1)C/S:Client/Server,客户端/服务端。
特点:需要在客户端和服务端都需要安装编写的软件,维护较麻烦。
好处:可以减轻服务端的压力。
(2)B/S:Browser/Server,浏览器/服务端。
特点:客户端不用单独编写软件。因为客户端用的就是浏览器。对于软件升级,只需考虑服务端即可。
弊端:所有的程序都运行在服务端,客户端的浏览器毕竟解析能力较弱。
3、 网络通信三要素:
IP地址、端口号、传输协议(通用协议TCP/IP)
(1)IP地址
分为A、B、C、D 段。
本地回环地址(默认IP 地址):127.0.0.1(可以用来测试网卡)
主机名:localhost(默认)
(2)端口号:
数字标识,用于标识进程的逻辑地址。
分为物理端口和逻辑端口。一般网络应用程序都有数字进行标识,称呼这个数字为端口,也就是逻辑端口。而且一个网络应用程序对应多个不同的(数字)端口。
有效端口:0~65535,其中0~1024为系统使用或保留端口。
(3)传输协议
常见协议:TCP协议、UDP协议。
4、 计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
5、 各种网络分类方式:
A: 按网络覆盖范围划分
局域网(几米至10 公里以内) 城域网(10~100 公里)
广域网(几百公里到几千公里) 国际互联网
B: 按网络拓扑结构划分
总线型网络 星形网络 环型网络 树状网络 混合型网络
C: 按传输介质划分
有线网 无线网
D: 按网络使用性质划分
公用网 专用网
二、IP地址(InetAddress)
1、 IP地址=网络号码+主机地址。
A 类IP 地址:第一段号码为网络号码,剩下的三段号码为本地计算机的号码
B 类IP 地址:前二段号码为网络号码,剩下的二段号码为本地计算机的号码
C 类IP 地址:前三段号码为网络号码,剩下的一段号码为本地计算机的号码
特殊地址:
127.0.0.1:回环地址,可用于测试本机的网络是否有问题。在命令行窗口输入ping 127.0.0.1。
ipconfig:查看本机IP地址
xxx.xxx.xxx.0网络地址
xxx.xxx.xxx.255广播地址
2、 InetAddress类
(1)无构造函数,封装的是IP地址,可通过getLocalHost()方法获取InetAddress对象,此方法是静态的,返回本类对象。
(2)方法:
1)static InetAddress getLocalHost():返回本地主机。
2)static InetAddress getByName(String host):获取指定主机的IP和主机名。
3)static InetAddress[] getAllByName(String host):在给定主机名的情况下根据系统上配置的名称服务返回IP地址所组成的数组。返回对象不唯一时,用此方法。
4)String getHostAddress():返回IP地址字符串(文本形式)。
5)String getHostName():返回IP地址的主机名。
代码示例:
import java.net.InetAddress; import java.net.UnknownHostException; public class IPDemo { public static void main(String[] args) throws UnknownHostException { //获得本地主机地址 InetAddress ia=InetAddress.getLocalHost(); System.out.println(ia.getHostName()+":"+ia.getHostAddress());//获得名称和ip地址 InetAddress[] ia1=InetAddress.getAllByName("www.baidu.com"); for(InetAddress ia2:ia1)//获得所有主机地址 System.out.println(ia2.getHostName()+":"+ia2.getHostAddress()); } }
三、UDP
1、 UDP概述
(1)特点:
a、面向无连接,即将数据及源和目的封装成数据包中,不建立链接的发送
b、每个数据包的大小限制在64K之内
c、因无连接,是不可靠的协议
d、不建立连接,速度快。
(2)弊端:容易丢失数据包。
(3)举例:聊天、视频会议、桌面共享都可以作为UDP传输。UDP相当于步话机。
2、 UDP传输
(1)Socket
Socket:英文译“插座”、”套接字”。
网络编程其实就是Socket 编程。Socket 就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket 间的通信。
数据在两个Socket 间通过IO 传输。
(2)UDP 的Socket 服务如何建立?
1) DatagramSocket 与DatagramPacket
2) 建立发送端、接收端
3) 建立数据包
4)调用Socket 的发送接收方法
5)关闭Socket。
3、 DatagramSocket
(1)DatagramSocket类:用来发送和接收数据报包的套接字。
(2)主要方法:
receive(DatagramPacket p):从此套接字接收数据报包。
send(DatagramPacket p):从此套接字发送数据报包。
4、 DatagramPacket
(1)DatagramPacket类:表示数据报包,用来实现无线接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。
(2)主要方法:
InetAddress getAddress :返回IP地址(对方的)
byte[] getData:返回数据缓冲区
int getLength():返回将要发送或接收到的数据长度
int getPort():返回端口号(对方的)
5、 UDP发送接收代码示例:
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class UDPSend { public static void main(String[] args) throws IOException { //1,创建udp服务,通过DatagramSocket对象 DatagramSocket ds=new DatagramSocket(); //2,确定数据,并封装成数据包 byte[] data="udp".getBytes(); DatagramPacket dp=new DatagramPacket(data,data.length,InetAddress.getByName("192.168.1.11"),10000); //3,通过socket服务,将已有的数据包发送出去,通过send方法 ds.send(dp); //关闭资源 ds.close(); } } public class UDPRece { public static void main(String[] args) throws IOException { DatagramSocket ds=new DatagramSocket(10000); while(true){ byte[] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,buf.length); ds.receive(dp); String ip=dp.getAddress().getHostAddress(); String data=new String(dp.getData(),0,dp.getLength()); int port=dp.getPort(); System.out.println(ip+":"+data+":"+port); } } }
6、 编写一个聊天程序
有收数据的部分 、 发数据的部分,这两部分需要同时执行,那就需要用到多线程技术。
代码示例:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.*; /* 编写一个聊天程序 有收数据的部分 、 发数据的部分 这两部分需要同时执行 那就需要用到多线程技术 */ public class ChatDemo { public static void main(String[] args) throws IOException { DatagramSocket sends=new DatagramSocket(); DatagramSocket reces=new DatagramSocket(10001); //启动发送端和接受断线程 new Thread(new Send(sends)).start(); new Thread(new Rece(reces)).start(); } } class Send implements Runnable{//发送端 private DatagramSocket ds; Send(DatagramSocket ds){ this.ds=ds; } public void run() { try { BufferedReader bufr=new BufferedReader( new InputStreamReader(System.in)); String line=null; while((line=bufr.readLine())!=null){ if("886".equals(line)) break; byte[] buf=line.getBytes(); DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.11"),10001); ds.send(dp); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } ds.close(); } } class Rece implements Runnable{//接收端 private DatagramSocket ds; Rece(DatagramSocket ds){ this.ds=ds; } public void run() { try { while(true){ byte[] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,buf.length); ds.receive(dp); String ip=dp.getAddress().getHostAddress(); String data=new String(dp.getData(),0,dp.getLength()); int port=dp.getPort(); System.out.println(ip+":"+data+":"+port); } } catch (IOException e) { e.printStackTrace(); } } }
四、TCP
1、 TCP概述
(1)特点:
a、面向连接,在建立连接后,形成传输数据的通道
b、在连接中进行大数据量的传输
c、通过三次握手完成连接,是可靠的协议
d、必须建立连接,效率稍慢
(2)TCP是面向连接的,必须连接成功才能传输数据,应用于下载等程序上。三次握手:第一次本方发送请求,第二次对方确认连接,第三次本方再次确认连接成功。
2、 TCP传输
(1)如何建立TCP?
1)Socket 和ServerSocket
2)建立客户端和服务器端
3)建立连接后,通过Socket 中的IO 流进行数据传输
4)关闭Socket。
3、 Socket
(1)Socket类:此类实现客户端套接字。套接字是两套机器间通讯的端点。步骤:创建Socket服务,并指定连接的主机护端口。
(2)构造函数:
Socket():创建空参数的客户端对象,一般用于服务端接收数据
Socket(String host,int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
(3)主要方法:
connect(SocketAddress endpoint,int timeout):将套接字连接到指定服务器,并指定一个超时值。
InetAddress getInetAddress():返回套接字的地址
shutdownInput():将此套接字的输入流置于“流的末尾”
shutdownOutput:禁用此套接字的输出流。
InputStream getInputStream():返回此套接字的输入流,Socket对象调用
OutputStream getOutputStream():返回套接字的输出流,Socket对象调用
4、 ServerSocket
(1)ServerSocket:服务器端。
(2)建立服务器端的步骤:
1)建立服务端的Socket服务,并监听一个端口。
2)获取连接过来的客户对象,通过ServerSocket的accept()方法,此方法是阻塞式的,如果服务端没有连接到就会一直等待
3)客户端如果发过来数据,则服务端要使用对应的客户端对象,并获取到该客户端对象的读取流读取发过来的数据,并输出到指定目的地。
4)关闭服务端(可选)。一般服务端是常开的,因为在实际应用中,随时有客户端在请求连接和服务。但这里需要定时关闭客户端对象流,避免某一个客户端长时间占用服务器端。
(3)构造函数:
ServerSocket():创建非绑定服务器套接字
ServerSocket(int port):创建绑定特定端口的服务器套接字。
ServerSocket(int port,int backlog):利用指定的backlog 创建服务器套接字并将其绑定到指定的本地端口号,backlog 是指能连接到服务器的客户端的同时的最大个数(就是客户端同时在线个数)。
(4)主要方法:
Socket accept():监听并接受到此套接字的连接。
5、 演示客户端和服务端
(1)客户端上传文件到服务端
代码示例:
import java.io.*; import java.net.*; public class TextClient { public static void main(String[] args) throws IOException { Socket s=new Socket("192.168.1.11",10008); BufferedReader bufr=new BufferedReader( new FileReader("file.txt")); PrintWriter out=new PrintWriter(s.getOutputStream(),true); String line=null; while((line=bufr.readLine())!=null){//读取每行 out.println(line); out.flush(); } s.shutdownOutput();//结束标识 BufferedReader bufr1=new BufferedReader( new InputStreamReader(s.getInputStream())); String str=bufr1.readLine(); System.out.println(str); } } public class TextServer { public static void main(String[] args) throws IOException { ServerSocket ss=new ServerSocket(10008); Socket s=ss.accept();//接收客户端 BufferedReader bufr=new BufferedReader( new InputStreamReader(s.getInputStream())); PrintWriter out=new PrintWriter(new FileWriter("server.txt"),true); String line=null; while((line=bufr.readLine())!=null){ if("over".equals(line))//结束“over” break; out.println(line); out.flush(); } PrintWriter out1=new PrintWriter(s.getOutputStream(),true); out1.println("完成"); } }
(2)客户端上传图片给服务端,服务端反馈结果。
代码示例:
import java.io.*; import java.net.*; public class PicClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket s=new Socket("192.168.1.11",10010); FileInputStream fis=new FileInputStream("1.jpg"); OutputStream out=s.getOutputStream(); byte[] buf=new byte[1024]; int len=0; while((len=fis.read(buf))!=-1){ out.write(buf,0,len); out.flush(); } s.shutdownOutput();//结束标识 InputStream in=s.getInputStream(); byte[] buf1=new byte[1024]; int num=in.read(buf1); System.out.println(new String(buf1,0,num)); fis.close(); s.close(); } } class PicThread implements Runnable{ private Socket s; PicThread(Socket s){ this.s=s; } public void run() { String ip=s.getInetAddress().getHostName(); System.out.println(ip+"...connect"); try { InputStream in=s.getInputStream(); FileOutputStream fos=new FileOutputStream("sever.jpg"); byte[] buf=new byte[1024]; int len=0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); } java.io.OutputStream out=s.getOutputStream(); out.write("上传成功".getBytes()); fos.close(); s.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } public class PicServer { public static void main(String[] args) throws UnknownHostException, IOException { ServerSocket ss=new ServerSocket(10010); while(true){ Socket s=ss.accept(); new Thread(new PicThread(s)).start(); } // ss.close(); } }
五、URL
1、 URL类:代表一个统一资源定位符,它是指向互联网“资源”指针。
2、 构造函数:
URL(Stirng spec):根据String 表示形式创建URL 对象
URL(Stirng protocol , String host , int port , String file):根据指定protocol、host、port 号和file 创建URL 对象。Protocol 代表协议。
3、 主要方法:
String getFile():获取此 URL 的文件名。
String getHost():获取此 URL 的主机名(如果适用)。
String getPath():获取此 URL 的路径部分。
int getPort():获取此 URL 的端口号。
String getProtocol():获取此 URL 的协议名称。
String getQuery():获取此 URL 的查询部。
URLConnection openConnection():返回一个URLConnection 对象,它表示到URL 所引用的远程对象的连接。也就是调用此对象,就会连接URL 主机,返回主机对象。每次调用此连接URL的协议处理程序的openConnection()方法都打开一个新的连接。
InputStream OpenStream():打开此URL 的连接,并返回一个用于从该连接读入的InputStream;相当于openConnection().getInputStream()此语句。
String getConnectionType():返回连接的头字段值。
4、 代码示例:
import java.io.*; import java.net.*; import org.omg.CORBA.portable.InputStream; public class URLConnectionDemo { public static void main(String[] args) throws Exception { URL url=new URL("http://www.sina.com.cn/"); URLConnection conn=url.openConnection(); System.out.println(conn); java.io.InputStream in=conn.getInputStream(); byte[] buf=new byte[1024]; int len=in.read(buf); System.out.println(new String(buf,0,len)); } }
相关文章推荐
- 黑马程序员--JAVA网络编程
- 黑马程序员——Java基础--网络编程
- 黑马程序员_王康java 网络编程
- 黑马程序员-13-java网络编程-概念及UDP、TCP连接
- 黑马程序员—21—java基础:有关网络编程的学习笔记和学习心得体会
- 黑马程序员_java网络编程
- 黑马程序员-Java-网络编程-day23
- 黑马程序员_java网络编程概述
- 黑马程序员:Java网络编程
- 黑马程序员——Java基础---网络编程(TCP编程)
- 黑马程序员—11、JAVA基础&网络编程
- java网络编程 tcp 黑马程序员学习笔记(11)
- 黑马程序员 Java基础 ---> 网络编程
- 黑马程序员----------Java网络编程(Socket编程)笔记
- 黑马程序员_java高级篇网络编程TCP实战Day8(上)
- 黑马程序员——Java之网络编程
- 黑马程序员_java网络编程总结
- 黑马程序员——Java基础---网络编程
- 黑马程序员——java高新技术——网络编程
- 黑马程序员_JAVA网络编程