黑马程序员-----网络编程总结(一)

来源:互联网 发布:php隐藏域名跳转代码 编辑:程序博客网 时间:2024/04/30 22:16

------- android培训、java培训、期待与您交流! ---------- 

一、网络知识基础

/*
 * 网络编程
 * OSI模型:
* 应用层
* 表示层
* 会话层
* 传输层
* 网络层
* 数据链路层
* 物理层

 * TCP/IP模型:
* 应用层
* 传输层
* 网际层
* 物理主机及网络层
 * 
 * IP地址:分为4段。对象InetAddress
 * 本地回环地址:127.0.0.1  主机名:localhost
 *  端口号:
 *  用于标识进程的逻辑地址,不通的进程的标识。
 *  有效端口0~65535 其中0~1024是系统使用的或保留的端口
 *  
 *  传输协议:
 *  通讯的规则
 *  常见协议:TCP UDP
 *  
 *  UDP:
 *  将数据源和目的封装在数据包中,面向无连接
 *  每个数据的大小限制在64k内
 *  因为无连接,是不可靠的传输
 *  不需要建立连接,速度快
 *  例如:QQ聊天
 *  
 *  TCP:
 *  面向连接,形成传输数据的通道,数据大小没有限制
 *  在连接中进行大量数据传输
 *  通过三次握手完成连接,是可靠协议
 *  必须建立连接,效率会稍低。
 *  
 *  Socket
 *  Socket 就是为网络服务提供的一种机制
 *  通信的两端都有Socket
 *  网络通信其实就是Socket之间的通信
 *  数据在两个Socket之间通过IO传输
 *
 */


二、UDP练习

package day23;import java.io.IOException;import java.net.*;/* * 需求:通过udp传输方式,将一段数据发送出去 * 思路、: * 1,建立udpSocket服务 * 2,提供数据,并将数据封包 * 3,通过Socket服务的发送功能建设过户数据发送出去 * 4,关闭资源 *  * */public class UdpDemo {public static void main(String[] args) throws IOException {//1,创建udp服务,通过DatagramSocket对象DatagramSocket ds = new DatagramSocket();//确定数据,并将数据封包byte[] buf = "udp lai le".getBytes();DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 9001);//3,通过socket服务,将已有的数据包发送出去,通过send方法ds.send(dp); //4,关闭资源ds.close();}


package day23;/*需求: * 定义一个应用程序,用于接收udp协议传输数据并处理 *  * 思路: * 1,定义一个udpSocket服务,通常就会监听一个端口,其实就是给这个用于程序定义一个数字表示 *      方便与明确哪个数据过来可已处理 * 2,定义一个数据包,因为要存储接收到的字节数据,因为数据包对象中油更多的功能可以提取字节数据的不通的信息 * 3,通过Socket服务的receive方法将收到的数据存入已定义好的数据包中 * 4,通过数据包对象的特有功能,将这些不通的数据取出,打印在控制台上 * 5,关闭资源 * */import java.io.IOException;import java.net.*;public class UdpReceive {public static void main(String[] args) throws IOException {//1,创建udpSocket服务,指定一个端点DatagramSocket ds = new DatagramSocket(9001);while(true){//2,定义数据包,用于存储数据byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);//3,通过receive方法将收到的数据存储到数据包中ds.receive(dp); //阻塞式方法//4,通过数据包的方法获取其中的数据String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(), 0, dp.getLength());int port = dp.getPort();System.out.println(ip+"::"+data+"::"+port);//5,关闭资源ds.close();}}}

三、聊天程序

package day23;import java.net.*;import java.io.*;/* * 编写一个聊天程序 * 有收数据和发数据的部分 * 这两部分需要同时执行 * 那就需要用到多线程 * 一个线程控制接收,一个线程控制发送 *  * 因为收和发是不一致的,所以要定义两个方法 * 而且这两个方法要封装在不同的类中。 *  * */class Send implements Runnable{private DatagramSocket ds ;public 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("127.0.0.255"),9999);ds.send(dp);}} catch (Exception e) {throw new RuntimeException("发送端失败。");}}}class Rece implements Runnable{private DatagramSocket ds ;public Rece(DatagramSocket ds){this.ds = ds;}public void run() {try {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());System.out.println(ip+":"+data);} catch (Exception e){throw new RuntimeException("接收端失败。");}}}public class ChatDemo {public static void main(String[] args) throws SocketException {DatagramSocket sendSocket = new DatagramSocket();DatagramSocket receSocket = new DatagramSocket(10000);new Thread(new Send(sendSocket)).start(); new Thread(new Rece(receSocket)).start(); }}

四、TCP练习

package day23;import java.net.*;import java.io.*;/* * TCP传输: * 1,tcp分为客户端和服务端 * 2,客户端对应 Socket,服务端对应 ServerSocket *  * *//* * 客户端:通过出啊月socket对象,发现该对象建立时,就可以去连接指定主机 * 因为tcp面向连接,所以在建立socket时,就要有服务端存在。形成通路后,在该通路进行数据的传输 *  *  * 需求:给服务端发送一个文本数据 *  * 步骤: * 1,创建Socket服务,并指定要连接的主机和端口 *  */class TcpClient {public static void main(String[] args ) throws UnknownHostException, IOException {//创建客户端的Socket服务,指定目的主机和端口Socket s = new Socket("127.0.0.1", 10002);//为了发送数据,应该获取socket流中的输出流OutputStream out = s.getOutputStream();out.write("tcp  lai le ".getBytes() );s.close();}} /* * 需求、;定义端点接收数据并打印在控制台上 *  * 服务端: * 1,建立服务端的socket  ServerSocket(); 并监听一个端口 * 2,获取连接过来的客户端对象 * 通过ServerSocket 的accept方法,没有连接就会等,所以这个方法是阻塞式的 * 3,客户端如果发过来数据,那么服务端就要使用对应的客户端对象,并获取到改客户端对象的读取流来读取发过来的数据 * 4,关闭服务端(可选) *  *  * */class TcpServer {public static void main(String[] args ) throws UnknownHostException, IOException {//创建客户端的Socket服务,指定目的主机和端口ServerSocket ss = new ServerSocket(10002);//通过accept方法连获取连接过来的客户端对象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();}} public class TcpSoket {public static void main(String[] args) {}}

package day23;import java.net.*;import java.io.*;/* * 演示:tcp传的客户端和服务端的互访 * *//* * 客户端: * 1,建立socket服务,指定要连接的主机和端口 * 2,获取socket流中的输出流,将数据写到该流中,通过网络发送给服务端 * 3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印 * 4,关闭客户端资源。 * */class TcpClient2 {public static void main(String[] args) throws UnknownHostException, IOException {Socket s = new Socket("192.168.131.128", 10003);OutputStream out = s.getOutputStream();out.write("服务端,你好".getBytes());InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf, 0, len));s.close();}}class TcpServer2 {public static void main(String[] args) throws IOException {ServerSocket ss = new ServerSocket(10003);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"...conneted");InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf, 0, len));OutputStream out = s.getOutputStream();out.write("客户端1,你也好。".getBytes());}}

五、文本转换器小程序

package day23;import java.net.*;import java.io.*;/* * 需求:建立一个文本转换服务器 * 客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端 * 而且客户端可以不断的进行文本转换,当客户端输入over时,转换结束。 *  * 分析: * 客户端: * 既然是操作数据,那么就可以使用IO技术,并按照IO的操作规律来思考 * 源:键盘录入 * 目的:网络输出流 * 而且操作的是文本数据,可以选择字符流。 *  * 步骤、: * 1,建立服务 * 2,获取键盘录入 * 3,将数据发给客户端 * 4,获取服务端返回的大写数据 * 5,结束,关闭资源 *  * 都是文本数据,可以使用字符操作流进行操作,同时提高效率,加入缓冲。 *  *  *  *  *  * */class TransClient {public static void main(String[] args) throws UnknownHostException, IOException {Socket s = new Socket("127.0.0.1", 10005);//定义读取键盘数据的流对象BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//定义目的,将数据写入Socket流//BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//定义一个Socket读取流,读取服务端返回的大写信息PrintWriter out = new PrintWriter(s.getOutputStream(),true);BufferedReader bufIn= new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;while((line=bufr.readLine())!=null) {if("over".equals(line))break;//bufOut.write(line);//bufOut.newLine(); //加换行符//bufOut.flush();out.print(line); String str = bufIn.readLine();System.out.println("server"+str);}bufr.close();s.close();}}/* * 服务端: * 源:socket读取流 * 目的:socket输出流 * 都是文本,装饰! *  */class TransServer {public static void main(String[] args) throws IOException {ServerSocket ss = new ServerSocket(10005);Socket s = ss.accept();String ip = ss.getInetAddress().getHostAddress();System.out.println(ip+"...conneted");//读取流中的数据BufferedReader bufIn= new BufferedReader(new InputStreamReader(s.getInputStream()));//目的:Socket输出流,将大写数据写入到Socket输出流,并发送给客户端//BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));PrintWriter out = new PrintWriter(s.getOutputStream(),true);String line = null;while((line=bufIn.readLine())!=null) {//bufOut.write(line.toUpperCase());//bufOut.newLine(); //加换行符//bufOut.flush();out.println(line.toUpperCase());}s.close();ss.close();}}/*该例子 出现的问题 * 现象:客户端和服务端都在莫名的等待,因为客户端和服务端都有阻塞式的方法。 * 这些方法都没有读到结束标记,那么就一直等二导致两端都在等待。 *  * */



0 0
原创粉丝点击