黑马程序员_Java基础_网络编程
2014-02-06 12:08
387 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
一、简介
Java的网络编程提供了两种通讯协议,UDP(数据报协议)与TCP(传输控制协议),网络通讯有三个要素:1、IP地址,2、端口号,3、网络协议
UDP与TCP的区别:
UDP将数据及源和目的封装成数据包,不需要建立链接,每个数据报的大小在现状在64k内,因无连接,所以是不可靠的协议,不需要建立连接,速度快。
TCP建立连接,形成传输数据的通道,在连接中进行大数据量传输,通过三次握手完成连接,是可靠协议,必须建立连接,效率会稍低。
二、UDP协议简单例子与知识点
在UDP协议中,一个通讯路径中有两个端点,一个是接收端,一个是发送端。
发送端:实例化UDP连接的类DatagramSocket(端口号(可选)),封装数据报包DatagramPacket,数据报包相当于邮件包,里面需要封装数据,数据的大小,发送的目的地(ip与端口),最后通过send方法发送数据
接收端:实例化UDP连接DatagramSocket(必填) 此时端口号应该明确说明,因为这样才能让发送端更方便的知道接收方的地址,在接受数据之前,需要准备接收数据的容器,也就是DatagramPacket数据报包,接收数据调用receive()方法接收数据,封装到DatagramPacket包中,调用数据报包的方法,获取发送端的信息与数据,有一个小的知识点在这里提下,就是发送端数据报包的IP地址最后一位为255的话,就能够实现广播的效果,例如:192.168.0.255在这个网段的用户如果存在端口号一致的服务,都能接受到数据的。
例子:从键盘上输入一段文字,通过UDP发送给接收端,接收端,接收到数据显示在控制台上
Java中使用Socket(套接字)完成TCP程序的开发,使用此类可以方便的建立可靠的、双向的、持续的、点对点的通讯连接
TCP里面有两个重要的类:Socket类与ServerSocket类,ServerSocket类主要用在服务端程序的开发上(服务端一般都是多线程的),用于接收客户端的连接请求,常用的方法:
构造方法:ServerSocket(int port),创建ServerSocket实例,用于监听指定端口
方法:
accept();等待客户端连接,是一个阻塞式方法
getInetAddress();得到IP
close();关闭连接
在服务端每次运行时都会使用accept()方法等待客户端的请求,当有客户端请求过来时,说返回一个Socket对象,该对象就是一个客户端对象,Socket对象常用的方法有:
构造方法:Socket(String host,int port),构造Socket对象,同时指定要连接的服务器主机与端口号
方法:
getInputStream()返回Socket对象的输入流
getOutputStream()返回Socket对象的输出流
close()关闭连接
分析学习下面最简单的TCP程序(这里先使用单线程)
服务端代码
客户端代码
下面使用多线程的方式完成服务端代码的编写,支持多线程并发访问
需求:完成图片上传,服务器端支持多个客户端并发上传图片
服务端代码:
客户端代码:
我在做测试的时候,复制一份客户端启动,模拟多个客户端并发请求服务端...
最后,还有一个知识点需要点出,就是HttpURLConnection,这个类的使用方法在JavaIO里面有个例子,就是模拟多线程下载文件。
总结:
在网络编程开发思路都是一样的,获取服务端连接,发送请求,得到服务端反馈信息。
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
一、简介
Java的网络编程提供了两种通讯协议,UDP(数据报协议)与TCP(传输控制协议),网络通讯有三个要素:1、IP地址,2、端口号,3、网络协议
UDP与TCP的区别:
UDP将数据及源和目的封装成数据包,不需要建立链接,每个数据报的大小在现状在64k内,因无连接,所以是不可靠的协议,不需要建立连接,速度快。
TCP建立连接,形成传输数据的通道,在连接中进行大数据量传输,通过三次握手完成连接,是可靠协议,必须建立连接,效率会稍低。
二、UDP协议简单例子与知识点
在UDP协议中,一个通讯路径中有两个端点,一个是接收端,一个是发送端。
发送端:实例化UDP连接的类DatagramSocket(端口号(可选)),封装数据报包DatagramPacket,数据报包相当于邮件包,里面需要封装数据,数据的大小,发送的目的地(ip与端口),最后通过send方法发送数据
接收端:实例化UDP连接DatagramSocket(必填) 此时端口号应该明确说明,因为这样才能让发送端更方便的知道接收方的地址,在接受数据之前,需要准备接收数据的容器,也就是DatagramPacket数据报包,接收数据调用receive()方法接收数据,封装到DatagramPacket包中,调用数据报包的方法,获取发送端的信息与数据,有一个小的知识点在这里提下,就是发送端数据报包的IP地址最后一位为255的话,就能够实现广播的效果,例如:192.168.0.255在这个网段的用户如果存在端口号一致的服务,都能接受到数据的。
例子:从键盘上输入一段文字,通过UDP发送给接收端,接收端,接收到数据显示在控制台上
package com.itheima.net; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * 网络编程之UDP程序设计 * 模拟网络通讯,发送端发送数据,接收端接收到数据并打印在控制台上 */ public class UDPDemo { public static void main(String[] args) throws Exception{ //启动程序 new Thread(new UDPReceive()).start(); new Thread(new UDPSend()).start(); } } /** * UDP发送端,把从控制台上接收到的数据发送到接收端 * 发送端实现Runnable接口 * */ class UDPSend implements Runnable{ public void run(){ send(); } //发送数据的方法 private void send(){ try{ //定义UDP发送端 DatagramSocket socket = new DatagramSocket(); //接收控制台输入的数据,因为我的控制台上UTF-8编码会出现乱码,这里我采用GBK编码 BufferedReader mReader = new BufferedReader(new InputStreamReader(System.in,"GBK")); String line = null; while((line = mReader.readLine())!=null){ byte[] buf = line.getBytes(); //定义要发送的数据包 DatagramPacket p = new DatagramPacket /*发送的数据 数据长度 发送到的地址 发送到那个端口*/ (buf, 0, buf.length, InetAddress.getByName("127.0.0.1"), 10000); socket.send(p); if(line.equals("bye")){//键盘接收数据不能够停止,所以需要定义一个终止符 break; } } System.out.println("发送端结束..."); }catch(Exception e){e.printStackTrace();} } } class UDPReceive implements Runnable{ public void run(){ try{ //定义UDP接收端,接收端采用多线程,接收端口号为10000的所有数据 DatagramSocket socket = new DatagramSocket(10000); while(true){ String result = receive(socket); System.out.println(result); //加上一下代码是为了终止接收端代码...终止接收端是不合理的。 if(result!=null && result.equals("bye")){ System.out.println("接收端结束..."); break; } } }catch(Exception e){e.printStackTrace();} } private String receive(DatagramSocket socket){ try{ //因为UDP接收数据的最大长度为64k,所以定义一个64K为长度的缓冲区 byte[] buf = new byte[64*1024]; //定义数据包,接收数据 DatagramPacket p = new DatagramPacket(buf, buf.length); socket.receive(p); //获取数据包中的数据 byte[] result = p.getData(); //得到发送端发送的数据 String data = new String(result,0,result.length); System.out.println(p.getAddress().getHostName()+p.getPort()+"说:"+data); if(data.trim().equals("bye")){ return "bye"; } return null; }catch(Exception e){e.printStackTrace();return null;} } }三、TCP协议与知识点
Java中使用Socket(套接字)完成TCP程序的开发,使用此类可以方便的建立可靠的、双向的、持续的、点对点的通讯连接
TCP里面有两个重要的类:Socket类与ServerSocket类,ServerSocket类主要用在服务端程序的开发上(服务端一般都是多线程的),用于接收客户端的连接请求,常用的方法:
构造方法:ServerSocket(int port),创建ServerSocket实例,用于监听指定端口
方法:
accept();等待客户端连接,是一个阻塞式方法
getInetAddress();得到IP
close();关闭连接
在服务端每次运行时都会使用accept()方法等待客户端的请求,当有客户端请求过来时,说返回一个Socket对象,该对象就是一个客户端对象,Socket对象常用的方法有:
构造方法:Socket(String host,int port),构造Socket对象,同时指定要连接的服务器主机与端口号
方法:
getInputStream()返回Socket对象的输入流
getOutputStream()返回Socket对象的输出流
close()关闭连接
分析学习下面最简单的TCP程序(这里先使用单线程)
服务端代码
package com.itheima.net; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; /** * 最简单的一个TCP程序,服务端 * 客户端输入一个小写字符,服务端把大写返回 */ public class TCPServerDemo1 { public static void main(String[] args) throws Exception{ //建立服务端 ServerSocket ss = new ServerSocket(10001); //等待客户端请求 Socket s = ss.accept(); //客户端请求到来,输出客户端信息 主机名 System.out.println(s.getInetAddress().getHostName()+"连接到我的服务...."); BufferedReader mReader = new BufferedReader(new InputStreamReader(s.getInputStream())); OutputStreamWriter writer = new OutputStreamWriter(s.getOutputStream()); String line = null; while((line = mReader.readLine())!=null){ //转换为大写发送出去 System.out.println("服务端接收到了数据...."); writer.write(line.toUpperCase()); //写出换行符,表示改行已经结束 writer.write(System.getProperty("line.separator")); writer.flush(); System.out.println("服务端数据返回。"); } //释放资源..... s.close(); ss.close(); } }
客户端代码
package com.itheima.net; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; /** * TCP程序的客户端 * @author Administrator * */ public class TCPClientDemo1 { public static void main(String[] args) throws Exception{ //向指定主机,这里是本机的指定端口10001发送请求 Socket s = new Socket("127.0.0.1", 10001); //获取键盘输入 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); //获取网络输出流对象,向服务端发送消息 OutputStreamWriter out = new OutputStreamWriter(s.getOutputStream()); //获取网络输入流对象,获取服务器返回值 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line = reader.readLine())!=null){ System.out.println(line+"---"); out.write(line); //写出换行符,表示改行已经结束 //当然这里也可以使用BufferedWriter,里面有newLine()方法很好用 //还有就有更简单的方法PrintWriter 构造方法里面有autoFlush这个选项。 out.write(System.getProperty("line.separator")); out.flush(); System.out.println("客户端发送出了数据"); System.out.println("服务端返回的数据是:"+in.readLine()); } } }
下面使用多线程的方式完成服务端代码的编写,支持多线程并发访问
需求:完成图片上传,服务器端支持多个客户端并发上传图片
服务端代码:
package com.itheima.net; import java.io.BufferedInputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * TCP程序服务端 * 目标:支持多个客户端并发访问 * 技术:Socket、多线程、IO */ public class TCPServerDemo2 { public static void main(String[] args) throws Exception{ //定义服务端 ServerSocket ss = new ServerSocket(10002); //每个客户端进入,都会开辟一个新的线程,处理 while(true){ //等待客户端连接 Socket s = ss.accept(); //开启线程 new Thread(new Server(s)).start(); } } } final class Server implements Runnable{ private Socket s;//每个服务端线程,对应一个客户端 public Server(Socket s){ this.s = s; } @Override public void run() { try{ System.out.println(s.getInetAddress().getHostName()+"连接到服务端...."); //得到网络输入流,接收客户端数据 BufferedInputStream in = new BufferedInputStream(s.getInputStream()); //得到文件输出流 PrintStream writer = new PrintStream(System.currentTimeMillis()+".jpg"); byte[] buf = new byte[1024]; int len = -1; while((len = in.read(buf))!=-1){ writer.write(buf, 0, len); } writer.close(); //得到网络输出流,通知客户端,完成了上传 PrintWriter out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()),true); out.println("上传成功!"); //下面是释放资源 s.close(); writer.close(); }catch(Exception e){ e.printStackTrace(); } } }
客户端代码:
package com.itheima.net; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.util.concurrent.TimeUnit; //模拟客户端--第一个 public class TCPClientDemo2 { public static void main(String[] args) throws Exception{ Socket s = new Socket("127.0.0.1", 10002); //获取网络输入流,接收服务端反馈信息 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); //获取网络输出流 PrintStream out = new PrintStream(new BufferedOutputStream(s.getOutputStream())); //获取读取文件流 BufferedInputStream reader = new BufferedInputStream(new FileInputStream("a.jpg")); byte[] buf = new byte[1024]; int len = -1; while((len = reader.read(buf))!=-1){ //模拟大文件 TimeUnit.SECONDS.sleep(1); out.write(buf,0,len); out.flush();//晕..我以为资源关闭会自动flush的..测试结果还需要手动flush } //结束标志 s.shutdownOutput(); reader.close(); //服务端返回数据 String line = in.readLine(); System.out.println("服务端说:"+line); s.close(); } }
我在做测试的时候,复制一份客户端启动,模拟多个客户端并发请求服务端...
最后,还有一个知识点需要点出,就是HttpURLConnection,这个类的使用方法在JavaIO里面有个例子,就是模拟多线程下载文件。
总结:
在网络编程开发思路都是一样的,获取服务端连接,发送请求,得到服务端反馈信息。
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net
相关文章推荐
- 黑马程序员—11、JAVA基础&网络编程
- 黑马程序员_java高级篇网络编程基础概念Day7
- 黑马程序员 Java基础--网络编程
- 黑马程序员—JAVA基础—网络编程
- 黑马程序员 4000 ——Java基础---网络编程
- 黑马程序员——Java基础---网络编程
- 黑马程序员_Java基础_网络编程_TCP协议编程,客户端服务端程序
- 黑马程序员_Java基础第24天_Java网络编程续
- 黑马程序员——Java基础---网络编程
- 黑马程序员--Java基础学习之网络编程(TCP、UDP、Socket、模拟发送和接收数据)
- 黑马程序员——java基础_网络编程
- 黑马程序员----JAVA基础----网络编程
- 黑马程序员-Java基础:网络编程
- 黑马程序员——java基础——Socket网络编程
- 黑马程序员_Java基础--网络编程
- 黑马程序员-----Java基础-----网络编程
- 黑马程序员——java基础知识之网络编程(二)
- 黑马程序员--Java基础--11网络编程
- 黑马程序员Java基础之网络编程(net)
- 黑马程序员—java基础学习--网络编程