Java语言是一门Internet语言,遇过不能够从Internet获取数据,Java就是死的,所以网络编程就是描述Java怎么从Internet获取数据!web
网络要素: IP: 地址<--解析-->主机名 InetAddress getByName(hostname); getHostAddress getHostName 端口:0-65535 协议: 1、TCP(面向链接,可靠,效率稍低。)---客户端:Socket 服务端ServerSocket 2、UDP(面向无链接,不可靠,速度快)---发送端,接收端。DatagramSocket ---- DatagramPacket(数据包)
在网络编程中,最重要部分非Socket莫属了,不管大小面试,对很是钟爱与Socket,由于Socket是网络通讯的基础,是网络通讯的最重要的工具面试
先用Socket实现UDP通讯编程
/* * 需求:创建UDP的发送端 * 思路: * 一、创建能够实现UDP传输的socket服务 * 二、明确具体发送的数据 * 三、经过socket服务将具体数据发送出去 * 四、关闭服务 */ //一、建立UDP服务 try { DatagramSocket ds = new DatagramSocket(); //二、明确数据 String str = "注意啦,UDP要来啦!"; //三、发送数据,将数据封装到数据包中 byte[] buf = str.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.137.1"), 9090); ds.send(dp); //四、关闭服务 ds.close(); } catch (SocketException e) { // TODO Auto-generated catch block System.out.println("UDP服务发送端启动失败"); e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("数据包发送失败"); e.printStackTrace(); }
/* * 需求:创建UDP接收端 * 思路: * 一、建立socket服务,明确接受数据的端口 * 二、接受数据包 * 三、将接收到的数据包中的数据取出来,取出的数据包括IP、data、port * 四、关闭服务 */ try { DatagramSocket ds = new DatagramSocket(9090); System.out.println("接收端启动成功!"); //三、接收数据包 byte[] buf = new byte[1000]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp);//阻塞式方法,使得Receive类开启时在等待状态,直到接收到数据才结束 //解析数据 StringBuilder sb = new StringBuilder(); sb.append("发送数据的IP为:"+dp.getAddress().getHostAddress()+"\n"); sb.append("接收到的数据为:"+new String(dp.getData(),0,dp.getLength())+"\n"); sb.append("接收数据端口为:"+dp.getPort()); System.out.println(sb.toString()); //四、关闭服务 ds.close(); } catch (SocketException e) { // TODO Auto-generated catch block System.out.println("接收端启动失败!"); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("数据包接收失败!"); }
//一个利用UDP协议写的一个半实现的聊天室
public class UDPChatRoom { /** * @param args * @throws SocketException */ public static void main(String[] args) throws SocketException { // TODO Auto-generated method stub /* * 需求:经过UDP协议完成一个聊天室程序(一个负责发送数据,另一个负责接收数据,两个同时进行) */ //建立socket服务。 DatagramSocket send = new DatagramSocket(10086); DatagramSocket rece = new DatagramSocket(10010); new Thread(new Send(send)).start(); new Thread(new Receive(rece)).start(); } } // 负责发送的任务,经过UDPsocket发送。 class Send implements Runnable{ //创建数据包 private DatagramSocket ds; public Send(DatagramSocket ds){ super(); this.ds = ds; } @Override public void run() { // TODO Auto-generated method stub //一、创建能够实现UDP传输的socket服务 //2读取数据 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; try { while((line = bufr.readLine())!=null){ if("over".equals(line)){ System.out.println(ds.getLocalSocketAddress()+":"+".....发送者离开聊天室"); } byte[] buf = line.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.137.1"),10010); //3发送数据 ds.send(dp); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 负责接收的任务 class Receive implements Runnable{ //创建数据包 private DatagramSocket ds; public Receive(DatagramSocket ds){ super(); this.ds = ds; } @Override public void run() { // TODO Auto-generated method stub while (true) { // 1,由于接收的数据最终都会存储到数据包中。而数据包中必须有字节数组。 byte[] buf = new byte[1024]; // 2,建立数据包对象。 DatagramPacket dp = new DatagramPacket(buf, buf.length); // 3,将收到的数据存储到数据包中。 try { ds.receive(dp); } catch (IOException e) { e.printStackTrace(); } // 4,获取数据。 String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(), 0, dp.getLength()); System.out.println(ip + ":" + data); if("over".equals(data)){ System.out.println(ip+".....接受者离开聊天室"); } } } }
再用Socket实现TCP通讯数组
/* * 需求:建立TCP服务端 * 思路: * 一、建立Socket服务器端服务,服务端为了能让客户端链接上,必须提供端口并监听一个端口 * 二、获取客户端对象,经过客户端的Socket流和对应的客户端进行通讯 * 三、获取客户端的Socket流的读取流 * 四、读取数据并显示在服务器端 * 五、关闭资源 */ //一、建立服务器端对象 ServerSocket ss = new ServerSocket(10000); System.out.println("Server is Opening!"); //二、获取客户端对象 Socket s= ss.accept(); String ip = s.getInetAddress().getHostAddress(); //三、经过客户端对象获取Socket流的读取 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String str = new String(buf,0,len); System.out.println(ip+":"+str); s.close(); ss.close();
/* * 需求:TCP客户端的创建 * 思路: * 一、创建TCP客户端服务 * 1.1由于是面向链接,必需要有链接才能够实现通讯 * 1.2在建立客户端的同时,就必须明确目的地址和端口 * 二、一旦链接创建,就有了传输数据的通道,就能够在通道中进行数据传输,数据的传输经过Socket-IO流实现 * 三、只要获取Socket-IO流中的写动做就能够进行发送数据到服务端 * 四、释放资源 */ //一、建立客户端对象。明确目的地址和端口 Socket s = new Socket("192.168.137.1",10000); System.out.println("Client is opening!"); //二、获取Socket流中的输出流,将数据发送到服务端 OutputStream os = s.getOutputStream(); //三、经过输出流写数据 os.write("注意啦,TCP要来啦!".getBytes()); //四、释放资源 s.close();
要实现高级一点的东西了,要利用TCP设计一个半实现的聊天工具服务器
/* * 服务端收到客户端的数据并反馈数据给客户端。应答。 */ //1,建立服务端socket对象。 ServerSocket ss = new ServerSocket(10004); System.out.println("ChatServer is Opening......"); //2,获取客户端对象。 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //3, 获取socket读取流。 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String str = new String(buf,0,len); System.out.println(str); //4,给客户端反馈数据。socket输出流。 OutputStream out = s.getOutputStream(); out.write("哦了,我知道你来了".getBytes()); //五、释放资源 s.close(); ss.close();
//需求:客户端发送数据给服务端,并读取服务端反馈的数据。 System.out.println("ChatClient is Opening....."); //1,建立socket客户端。 Socket s = new Socket("192.168.137.1",10004); //2,获取socket输出流。写数据。 OutputStream out = s.getOutputStream(); out.write("服务端,我来了.".getBytes()); //3,获取socket的读取流。读取服务端发回的数据。 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String str = new String(buf,0,len); System.out.println(str); //四、释放资源 s.close();
再高级一点,利用TCP协议进行传送文件了(包括图片、文本)网络
/* * 上传文本的客户端。读取本地文本数据,发送给服务端,服务端接收完毕后,回馈"上传成功"字样。 */ //客户端socket Socket s = new Socket("192.168.137.1",10005); System.out.println("上传文本客户端启动......"); //1,肯定数据源。本地文件文件 BufferedReader bufr = new BufferedReader(new FileReader("client.txt")); //2,肯定目的IP和Socket-IO输出流 PrintWriter out = new PrintWriter(s.getOutputStream(),true); String line = null; while((line=bufr.readLine())!=null){ out.println(line); } //使用socket的禁用输出流方法来中止向服务端发送数据。 s.shutdownOutput(); //3,经过socket读取流获取服务端返回的数据。 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String lineIn = bufIn.readLine();//阻塞式。 System.out.println(lineIn); //4,释放资源 bufr.close(); s.close();
/* * 上传文本的服务端。接收文本数据,并存储到文件中,服务端接收完毕后,回馈"上传成功"字样。 */ //1,服务端对象。 ServerSocket ss = new ServerSocket(10005); System.out.println("上传文本服务器端启动......."); //2,获取客户端。 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //3,获取读取流。肯定源,网络socket。 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); //4,肯定目的文件。 PrintWriter pw = new PrintWriter(new FileWriter("server.txt"),true); //5,频繁读写。 String line = null; while((line=bufIn.readLine())!=null){ pw.println(line); } //6,给客户端返回信息。 PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("上传成功"); //七、释放资源 pw.close(); s.close(); ss.close();
TCP的传输、上传、问题:两端等待的状况。说明有阻塞式方法。没有读取到结束标记。shutdown. web原理:并发访问,Server端:未来访的客户端都封装到了一个单独线程中。 ServerSocket server = new ServerSocket(10000); while(true) { Socket s = server.accept(); new Thread(new Task(s)).start(); }