黑马程序员——java基础知识之网络编程(一)
2015-04-14 22:19
851 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
(一)、网络编程的基础知识
1、网络编程的目的是什么?
就是为了实现直接或间接地通过网络与其他计算机进行通信。
2、要想实现网络编程要素
①找到对方的IP
②数据要发送到对方电脑上的应用程序,为了标示这些应用程序,所给这些网络应用程序都给数字标示,这些数字就叫做端口,它们是逻辑端口
③定义通信规则,这个通信规则叫做协议。国际上定义了通用的协议TCP/IP
3、网络模型
说明:一般来说开发处于传输层和网际层,应用层为:FTP和HTTP协议等,传输层为:UDP和TCP等,网际层为:IP。
通常用户操作的是应用层,而编程人员需要做的是传输层和网际层,用户在应用层操作的数据,经过逐层封包,最后到物理层发送到另一个模型中,再进行逐层解包
(二)、网络编程知识点详解
(1)、网络通讯要素
IP:
1、网络中设备的标示
2、不易记忆,可用主机名
3、本地回环地址:127.0.0.1 主机名:localhost
端口号:
有效端口:0—65535,其中0—1024是系统使用或预留端口
传输协议:
常见协议:TCP/IP
(2)、IP的具体知识
IP地址:java中对应的是InetAddress类,存在于java.net包中。
例子程序:
(3)、UDP传输详情知识点
举例子说明:
UDP传输进阶:
例子1、UDP键盘录入方法
例子2、用UDP传输模拟QQ聊天,要利用多线程。
(4)、TCP传输详情知识点
1、TCP的应用特点:
建立客户端(Socket)和服务端(ServerSocket);
建立连接后,通过Socket中的IO流进行数据的传输
关闭Socket
注意:客户端和服务器端是两个单独的应用程序
2、例子演示:
例子1:演示TCP传输
例子2:演示TCP的传输的客户端和服务端的相互访问。
例子3:建立一个文本转换服务器。
客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。
而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。
例子4:用客户端发文件给服务端,再由服务端把文件复制到本地硬盘。
(一)、网络编程的基础知识
1、网络编程的目的是什么?
就是为了实现直接或间接地通过网络与其他计算机进行通信。
2、要想实现网络编程要素
①找到对方的IP
②数据要发送到对方电脑上的应用程序,为了标示这些应用程序,所给这些网络应用程序都给数字标示,这些数字就叫做端口,它们是逻辑端口
③定义通信规则,这个通信规则叫做协议。国际上定义了通用的协议TCP/IP
3、网络模型
说明:一般来说开发处于传输层和网际层,应用层为:FTP和HTTP协议等,传输层为:UDP和TCP等,网际层为:IP。
通常用户操作的是应用层,而编程人员需要做的是传输层和网际层,用户在应用层操作的数据,经过逐层封包,最后到物理层发送到另一个模型中,再进行逐层解包
(二)、网络编程知识点详解
(1)、网络通讯要素
IP:
1、网络中设备的标示
2、不易记忆,可用主机名
3、本地回环地址:127.0.0.1 主机名:localhost
端口号:
有效端口:0—65535,其中0—1024是系统使用或预留端口
传输协议:
常见协议:TCP/IP
(2)、IP的具体知识
IP地址:java中对应的是InetAddress类,存在于java.net包中。
例子程序:
/* InetAddress类的具体方法: 1)static InetAddress getByName(String host):获取指定主机的IP和主机名。(最好用ip地址去获取,主机名需要解析) 2)static InetAddress[] getAllByName(String host):在给定主机名的情况下,根据系统上配置的名称服务返回IP地址所组成的数组。返回对象不唯一时,用此方法。 3)String getHostAddress():返回IP地址字符串文本形式,以IP地址为主。 4)String getHostName():返回IP地址主机名。 */ import java.net.*; class IPDemo { public static void main(String[] args) throws Exception { //InetAddress i = InetAddress.getLocalHost(); // System.out.println(i.toString()); // System.out.println("address:"+i.getHostAddress()); // System.out.println("name:"+i.getHostName()); InetAddress ia = InetAddress.getByName("thinkpad-sl400"); System.out.println("address:"+ia.getHostAddress()); System.out.println("name:"+ia.getHostName()); } }
(3)、UDP传输详情知识点
举例子说明:
package cn.dhj; import java.net.*; /* * 需求、利用udp传输方式,发送数据 1、创建udpsocket服务端口 2、提供数据,并将数据封包 3、利用socket服务的发送功能发送数据 4、关闭资源 */ public class UdpSend { public static void main() throws Exception{ byte[] buf = (new String("wo shi duan huang jun")).getBytes(); //1、创建udpsocket服务端口 DatagramSocket sp = new DatagramSocket(); //2、提供数据,并封装成数据包,用的是DatagramPacket(byte[] buf, int length, InetAddress address, int port)的方法 DatagramPacket pb = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),8888); //3、利用socket服务的发送功能发送数据 sp.send(pb); //关闭资源 sp.close(); } } /* * 定义udp的接收端。 思路: 1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。 方便于明确哪些数据过来该应用程序可以处理。 2,定义一个数据包,因为要存储接收到的字节数据。 因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。 3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。 4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。 5,关闭资源。 */ class udpReceive{ public static void main (String[] args)throws Exception{ DatagramSocket fs =new DatagramSocket(8888);//1,创建udp socket,建立端点。 while(true){ //2,定义数据包。用于存储数据。 byte[] buf = new byte[2014]; DatagramPacket js =new DatagramPacket(buf,buf.length); fs.receive(js);//3,通过服务的receive方法将收到数据存入数据包中。 //4,通过数据包的方法获取其中的数据 String data =new String(js.getAddress().getHostAddress()); System.out.println(data); //5,关闭资源 fs.close(); } } } /*总结: 1、通过类DatagramSocket,此类表示用发送和接收数据包的套接字,即Socket。 2、方法: 1)创建 UDPSocket发送服务对象: DatagramSocket(),不指定端口。DatagramSocket(int port),指定端口。 2)发送:void send(DatagramPacket p) 3)接收:void receive(DatagramPacket p) 其中DatagramPacket:数据报包用来实现无连接包投递服务的,每条报文仅根据该包中包含的信息从一台机器路由到另一台机器中。凡是带地址(InetAddress)的都是用于发送包的。 3、步骤 1)发送数据: a、建立UDPSocket服务,在此无需指定端口,也可以将端口加入。如果不指定的话,系统会随机分配一个端口,如第一次运行时端口为1093,那么第二次就会顺延为1094,再运行会一直顺延,因为之前的端口还没有得到释放,所以会顺延端口号值。 b、提供数据,并将数据封装到数据包中 c、通过socket服务的发送功能,将数据包发送出去 d、关闭资源 2)接收数据: a、定义UDPSocket服务。通常会监听一个端口,其实就是给这个接收网路应用程序定义数字标识,方便于明确哪些数据过来该应用程序可以处理。 b、定义一个数据包,用来存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。 c、通过socket服务的receive方法接收到的数据存入已定义好的数据包中 d、通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上 e、关闭资源 在定义接收数据的方法中,仍会在DatagramSocket构造函数中传入DatagramPacket的参数,这是因为收到的数据太多,需要解析,通过将数据封装成对象,易于解析,所以需要传入参数。 注意: 1、发送端与接收端是两个独立的运行程序。 2、在发送端,要在数据包对象中明确目的地IP及端口。 3、在接收端,要指定监听的端口。 */
UDP传输进阶:
例子1、UDP键盘录入方法
package cn.dhj; import java.io.*; import java.net.*; public class Udpsend2 { public static void main(String[] args) throws Exception{ //1、创建udp Socket服务,建立端点 DatagramSocket send = new DatagramSocket(); //2、确定数据,从键盘录入,并把键盘录入的数据封装成数据包 BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line = buff.readLine())!=null){ if(line.equalsIgnoreCase("exit")){ break; } byte[] buf = line.getBytes(); //3、通过Socket服务,将已有的数据包发送出去 send.send(data); } //4、关闭资源 send.close(); } } class Udprece { //1、创建udp Socket服务端口 DatagramSocket rece =new DatagramSocket(8888); while(true){ //2、定义数据包,用于存储数据 byte[] buf = new byte[2014]; DatagramPacket js =new DatagramPacket(buf,buf.length); //接收数据 rece.receive(js); //解析包,拿到包里面的数据和地址 String ip = js.getAddress().getHostAddress(); String data = new String(js.getData(),0,js.getLength()); System.out.println(ip+data); } } }
例子2、用UDP传输模拟QQ聊天,要利用多线程。
package cn.dhj; /* 编写一个聊天程序。 有收数据的部分,和发数据的部分。 这两部分需要同时执行。 那就需要用到多线程技术。 一个线程控制收,一个线程控制发。 因为收和发动作是不一致的,所以要定义两个run方法。 而且这两个方法要封装到不同的类中。 */ import java.io.*; import java.net.*; public class ChatTest { public static void main(String[] args) throws Exception{ DatagramSocket sendsocket = new DatagramSocket(); DatagramSocket receivesocket = new DatagramSocket(8888); new Thread(new Send( sendsocket)).start(); new Thread(new rece(receivesocket)).start(); } } class Send implements Runnable { private DatagramSocket ds; public Send(DatagramSocket ds) { super(); this.ds = ds; } public void run(){ try{ BufferedReader bufb = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((bufb.readLine())!=null){ byte[] buf = line.getBytes(); DatagramPacket pd = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.102.0.124"),8888); ds.send(pd); if("exit".equals(line))break; } ds.close(); }catch(Exception e){ System.out.println("发送端失败"); } } } class rece implements Runnable{ private DatagramSocket ds; public rece(DatagramSocket ds) { super(); this.ds = ds; } public void run(){ try{ while(true){ byte[] buf = new byte[2014]; DatagramPacket pd = new DatagramPacket(buf,buf.length); ds.receive(pd); String ip = pd.getAddress().getHostAddress(); String dada = new String(pd.getData(),0,pd.getLength()); if("exit".equals(dada)){ System.out.println("离开聊天室"); break; } System.out.println(ip+dada); } }catch(Exception e){ throw new RuntimeException("接收端失败"); } } }
(4)、TCP传输详情知识点
1、TCP的应用特点:
建立客户端(Socket)和服务端(ServerSocket);
建立连接后,通过Socket中的IO流进行数据的传输
关闭Socket
注意:客户端和服务器端是两个单独的应用程序
2、例子演示:
例子1:演示TCP传输
/* 1,tcp分客户端和服务端。 2,客户端对应的对象是Socket。 服务端对应的对象是ServerSocket。 客户端, 通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。 因为tcp是面向连接的。所以在建立socket服务时, 就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。 需求:给服务端发送给一个文本数据。 步骤: 1,创建Socket服务。并指定要连接的主机和端口。 */ import java.io.*; import java.net.*; class TcpClient { public static void main(String[] args) throws Exception { //创建客户端的socket服务。指定目的主机和端口 Socket s = new Socket("192.168.1.254",10003); //为了发送数据,应该获取socket流中的输出流。 OutputStream out = s.getOutputStream(); out.write("tcp ge men lai le ".getBytes()); s.close(); } } /* 需求:定义端点接收数据并打印在控制台上。 服务端: 1,建立服务端的socket服务。ServerSocket(); 并监听一个端口。 2,获取连接过来的客户端对象。 通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。 3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。 并打印在控制台。 4,关闭服务端。(可选) */ class TcpServer { public static void main(String[] args) throws Exception { //建立服务端socket服务。并监听一个端口。 ServerSocket ss = new ServerSocket(10003); //通过accept方法获取连接过来的客户端对象。 while(true) { Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len)); s.close();//关闭客户端. } //ss.close(); } } /* 总结:思路步骤: 客户端: 通过查阅Socket对象的API文档,发现在该对象在建立时,就可去连接指定主机,因为TCP是面向连接的,所以在建立Socket服务时,就要有服务端存在,并连接成功,形成通路后,再通过该通道进行数据的传输。 1)创建Socket服务,并指定要连接的主机端口。通路一建立,就会产生Socket流(包括输入流和输出流),通过方法获取 2)为了发送数据,应获取Socket中的输出流,如果要接收服务端的反馈信息,还需要获取Socket的输入流 3)通过输出流的write()方法将要发送的数据写入到流中 4)关闭Socket流资源 服务端: 服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。需监听一个端口。 1)建立服务端的Socket服务,并监听一个端口。通过ServerSocet带端口参数的构造函数 2)获取连接过来的客户对象,通过ServerSocket的accept()方法,此方法是阻塞式的,如果服务端没有连接到就会一直等待 3)客户端如果发过来数据,则服务端要使用对应的客户端对象,并获取到该客户端对象的读取流读取发过来的数据,并输出到指定目的地。 4)关闭服务端(可选)。一般服务端是常开的,因为在实际应用中,随时有客户端在请求连接和服务。但这里需要定时关闭客户端对象流,避免某一个客户端长时间占用服务器端。 */
例子2:演示TCP的传输的客户端和服务端的相互访问。
package cn.dhj; import java.io.*; import java.net.*; /* * 需求分析:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。 */ /* * 客户端:1、建立socket服务 * 2、获取socket流中的输出流:数据写到该流中。通过网络发送给服务端 * 输入流:将服务端反馈的数据获取到,并打印。 * 3、关闭资源 */ public class TCPclient { public static void main(String[] args) throws Exception{ Socket sd = new Socket("127.0.0.1",8888); OutputStream out = sd.getOutputStream(); out.write("你好 我是土豆 收到请回答".getBytes()); InputStream In = sd.getInputStream(); byte[] buf = new byte[2014]; int len =In.read(buf); System.out.println(new String(buf,0,len)); } } /* 服务端:1,建立服务端的socket服务。ServerSocket(); 并监听一个端口。 2,获取连接过来的客户端对象。 通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。 3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。 并打印在控制台。 4,关闭服务端。(可选) */ class TCPserver{ public static void main(String[] args) throws Exception{ ServerSocket ss = new ServerSocket(8888); while(true){ Socket s = ss.accept(); InputStream In = s.getInputStream(); byte[] buf = new byte[2014]; int len = In.read(buf); System.out.println(new String(buf,0,len)); OutputStream Out = s.getOutputStream(); Out.write("收到 收到 我是茄子".getBytes()); s.close; ss.close; } } }
例子3:建立一个文本转换服务器。
客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。
而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。
*/ package cn.dhj; import java.io.*; import java.net.*; /*需求:建立一个文本转换服务器。 客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。 而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。 * 客户端:1,建立服务。 2,获取键盘录入。 3,将数据发给服务端。 4,后去服务端返回的大写数据。 5,结束,关资源。 */ public class TCPTransclient { public static void main (String[] args) throws Exception{ //建立Socket服务 Socket s = new Socket("127.0.0.1",8888); //获取键盘录入 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //将数据发给服务端 PrintWriter out = new PrintWriter(s.getOutputStream(),true); //定义一个socket读取流,读取服务端返回的大写信息。 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line=bufr.readLine())!=null){ if("exit".equals(line)); break; out.println(line); String str =bufIn.readLine(); System.out.println("server:"+str); } bufr.close(); s.close(); } } class TCPTransserver{ public static void main(String[] args) throws Exception{ ServerSocket ss = new ServerSocket(8888); Socket s = ss.accept(); String ip =s.getInetAddress().getHostAddress(); //读取socket读取流中的数据。 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); //目的。socket输出流。将大写数据写入到socket输出流,并发送给客户端。 PrintWriter out = new PrintWriter(s.getOutputStream(),true); String line = null; while((line=bufIn.readLine())!=null) { if("over".equals(line)) break; System.out.println(line); out.println(line.toUpperCase()); } ss.close(); s.close(); } } /* 该例子出现的问题。 现象:客户端和服务端都在莫名的等待。 为什么呢? 因为客户端和服务端都有阻塞式方法。这些方法么没有读到结束标记。那么就一直等 而导致两端,都在等待。 */
例子4:用客户端发文件给服务端,再由服务端把文件复制到本地硬盘。
package cn.dhj; import java.io.*; import java.net.*; public class TCPfuzhiclient { public static void main(String[] args) throws Exception{ Socket s = new Socket("127.0.0.1",8888); BufferedReader bufIn =new BufferedReader(new FileReader("TCPclient.java")); PrintWriter out = new PrintWriter(s.getOutputStream(),true); String line = null; while((bufIn.readLine())!=null){ out.println(line); } s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1. BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream())); String str = bufr.readLine(); System.out.println(str); s.close(); bufIn.close(); } } class TCPfuzhiserver{ public static void main(String[] args) throws Exception{ ServerSocket ss = new ServerSocket(8888); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"....connected"); BufferedReader bufb = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter out = new PrintWriter(new FileWriter("TCPclient.java")); String line = null; while((line=bufb.readLine())!=null) { out.println(line); } PrintWriter pw = new PrintWriter(s.getOutputStream(),true); pw.println("上传成功"); out.close(); s.close(); ss.close(); } }
相关文章推荐
- 黑马程序员Java培训、Android培训_网络编程的基础知识
- 黑马程序员-Java基础知识预备之Java网络编程
- 黑马程序员 Java基础知识总结-网络编程
- 黑马程序员--网络编程--java学习日记10(基础知识)
- 黑马程序员---java基础知识(十):网络编程
- 黑马程序员——java基础知识之网络编程(二)
- 黑马程序员-java基础-网络基础知识,JAVA网络编程
- 黑马程序员 java基础之网络编程
- 黑马程序员_java基础笔记(08)...GUI,网络编程,正则表达式
- 黑马程序员_java基础笔记(08)...GUI,网络编程,正则表达式
- 黑马程序员java基础之网络编程
- Java基础知识:网络编程
- 黑马程序员——java基础--网络编程
- 黑马程序员 Java基础--网络编程
- 黑马程序员--Java基础--网络编程
- 黑马程序员——java基础——网络编程
- 黑马程序员------java基础----网络编程
- 黑马程序员--java基础--网络编程
- 黑马程序员--java基础--网络编程(UDP和TCP)
- 黑马程序员------Java基础学习------网络编程