Java网络编程:
1.1: 网络编程:对于我这个“研究不深”的网络菜鸟来说,我觉得网络编程就是实现计算机与计算机之间通信的编程。写些能够实现计算机与计算机之间的通信就行了(目前来说)。
1.2:一台计算机跟另外计算机通讯。
计算机与计算机通讯的三大要素:
1:ip地址---电脑
1.1:作用:唯一标识一台计算机。
回环地址:127.0.0.1==主机:localhost
主机地址作用:测试网卡是否正常。
2:找到相应的应用程序----端口号
端口号-----具有网络功能的应用程序的标识号,没有网络功能的程序具有端口号似乎没有用吧。端口号是用整数来表示:0-65535,正好是char类型数据的范围
端口是一个软件结构,被客户程序或服务程序用来发送和接收数据,一台服务器有256*256个端口。
0-1023是公认端口号,即已经公认定义或为将要公认定义的软件保留的
1024-65535是并没有公共定义的端口号,用户可以自己定义这些端口的作用。
端口与协议有关:TCP和UDP的端口互不相干
自定义端口最好别写前面的端口号,一般是写1024之后的。
关于端口号的详细说明:连接
3:计算机协议
3.1:UDP协议:视频传输会有得比较多。
3.2:TCP/IP协议,通讯所遵守的协议,这是很多协议的一个总称。
2:udp协议(比较少用)
2.1:InetAddress类(IP相关的类)。
1:通过ip地址获得InetAddress对象 InetAddress.getByName("ip地址");
2:获得本地的InetAddress InetAddress.getLocalHost()
3:获得对象的ip字符串 对象名.getHostAddress( )
4:获得对象的主机名 对象名.getHostName()
2.2:udp协议:收发的两端一般称作:发送端和接收端
1:特点:面向无连接:无论接收到是否开启,发送端都会将数据发送出去。
效率高,不可靠:UDP协议的传输效率是很高的,但是由于是向无连接的,所以发送出去的数据不一定会被接收到收到,而且在传输的过程中数据很可能会丢失(发送端发送一张2M的图片,接收端接收的可能只剩1M也说不定),所以这种协议不可靠。
发送和接收的是数据报包——Datagrampacket。
2:相关的类:
DatagramSocket, DatagramPacket.
3:关于UDP协议下DatagramSocket和DatagramPacket的案例
1 import java.io.BufferedInputStream; 2 3 import java.io.FileInputStream; 4 5 import java.io.IOException; 6 7 import java.net.DatagramPacket; 8 9 import java.net.DatagramSocket; 10 11 import java.net.InetAddress; 12 13 import java.net.SocketException; 14 15 16 17 /* 18 19 * 1:发送端发送一个文件(文本文件,图片)给接收端. 20 21 */ 22 23 public class Send {//发送端 24 25 public static void main(String[] args) { 26 27 //读取文件操作 28 29 BufferedInputStream bis = null; 30 31 //读取文件的数组 32 33 byte[] b1 = new byte[1024]; 34 35 //每次读取到的数组长度 36 37 int len = -1; 38 39 //创建UDP套接字 40 41 DatagramSocket ds = null; 42 43 //创建数据报包 44 45 DatagramPacket dp = null; 46 47 //创建数据报包要使用到的参数: 48 49 //1、字节数组(包数据)== 读取文件的数组 50 51 //2、包的长度 == 每次读取到的数组长度 52 53 //3、目标地址 54 55 InetAddress ia = null; 56 57 //4、地址端口 58 59 int port = 8888; 60 61 try { 62 63 ia = InetAddress.getLocalHost();//获取本机地址 64 65 //关联文件 66 67 bis = new BufferedInputStream(new FileInputStream("e:\\aa.mp3")); 68 69 //读取文件 70 71 while((len = bis.read(b1)) != -1){ 72 73 ds = new DatagramSocket(); 74 75 dp = new DatagramPacket(b1, len, ia, port); 76 77 ds.send(dp);//发送数据给接收端 78 79 } 80 81 //如果发送的数据为空了,就发送一次空的指示给接收端 82 83 if(len == -1){ 84 85 ds = new DatagramSocket(); 86 87 dp = new DatagramPacket(b1, 0, ia, port); 88 89 ds.send(dp);//发送数据给接收端 90 91 } 92 93 } catch (SocketException e) { 94 95 e.printStackTrace(); 96 97 } catch (IOException e) { 98 99 e.printStackTrace(); 100 101 }finally{ 102 103 try { 104 105 bis.close();//关闭流 106 107 } catch (IOException e) { 108 109 e.printStackTrace(); 110 111 } 112 113 ds.close();//关闭套接字资源 114 115 } 116 117 } 118 119 } 120 121
发送端代码
1 import java.io.BufferedOutputStream; 2 3 import java.io.FileOutputStream; 4 5 import java.io.IOException; 6 7 import java.net.DatagramPacket; 8 9 import java.net.DatagramSocket; 10 11 12 13 public class Receive {//接收端 14 15 public static void main(String[] args) { 16 17 //文件写出流 18 19 BufferedOutputStream bos = null; 20 21 //创建UDP套接字对象 22 23 DatagramSocket ds = null; 24 25 //数据报包 26 27 DatagramPacket dp = null; 28 29 //端口号 30 31 int port = 8888; 32 33 byte[] b = new byte[1024]; 34 35 int length = b.length; 36 37 try { 38 39 bos = new BufferedOutputStream(new FileOutputStream("e:\\bb.mp3")); 40 41 ds = new DatagramSocket(port); 42 43 while(true){ 44 45 dp = new DatagramPacket(b, 0, length); 46 47 //接收数据 48 49 ds.receive(dp); 50 51 //写出数据 52 53 bos.write(b, 0, dp.getLength()); 54 55 bos.flush(); 56 57 //接受文件的长度是0的时候跳出循环 58 59 if(dp.getLength()==0){ 60 61 break; 62 63 } 64 65 } 66 67 68 69 } catch (IOException e) { 70 71 // TODO Auto-generated catch block 72 73 e.printStackTrace(); 74 75 }finally{ 76 77 try { 78 79 bos.close(); 80 81 } catch (IOException e) { 82 83 // TODO Auto-generated catch block 84 85 e.printStackTrace(); 86 87 } 88 89 ds.close(); 90 91 } 92 93 } 94 95 }
接收端代码
3:tcp协议:相连接的两端一般称为客户端(Client)和服务器端(Server)。都是以流的形式来发送和接收数据。
1:特点:面向连接,效率没有udp高,可靠(三次握手)。
tcp连接有3次握手完成一次连接:
1:客户端连接服务器端。等待服务器端响应
2:服务器端给出一个响应给客户端
3:服务器端准备发送数据。
2:相关的类.
客户端:Socket
服务器端:ServerSocket
2.1:客户端发送"HelloWorld"给服务器端,运行时要先开启服务器端。
import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class ClientDemo1 {//客户端 public static void main(String[] args) throws IOException { //客户端套接字 Socket s = new Socket("127.0.0.1", 9999); //要发送的数据 String str = "HelloWorld"; //获取客户端的输出流 OutputStream os = s.getOutputStream(); //输出数据 os.write(str.getBytes()); os.close(); s.close(); } }
客户端代码
import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo1 {//服务器端 public static void main(String[] args) throws IOException { //服务器端套接字 ServerSocket ss = new ServerSocket(9999); //接受数据的Socket Socket s = ss.accept(); //接受数据相关的输入流 InputStream is = s.getInputStream(); byte[] b = new byte[1024]; int length = is.read(b); //打印数据 System.out.println(new String(b, 0, length)); } }
服务器端代码
3:两两聊天。但是不能够同时发送和接收数据。
一开始我的代码:两端即是客户端也是服务器端,造成这个的原因是不了解客户端与服务器端连接之后形成的“管道”是可以双向流动数据的。
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class ClientDemo4 { public static void main(String[] args)throws IOException { /* * 发送 */ String host = "127.0.0.1"; // String host = "10.16.153.62"; Socket s = new Socket(host, 9999); OutputStream os = s.getOutputStream(); Scanner sc = new Scanner(System.in); String str = null; /* * 接收 */ ServerSocket ss = new ServerSocket(8888); Socket s2 = ss.accept(); InputStream is = s2.getInputStream(); byte[] b = new byte[1024]; String str2 = null; int length = -1; String address = s2.getInetAddress().getHostAddress(); int port = s2.getPort(); while(true){ str = sc.nextLine(); os.write(str.getBytes()); if("886".equals(str)){ break; } length = is.read(b); str2 = new String(b, 0, length); System.out.println(address+":"+port+"\t"+str2); } } }
即是客户端也是服务器端之客户端
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class ServerDemo4 { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(9999); Socket s = ss.accept(); InputStream is = s.getInputStream(); byte[] b = new byte[1024]; int length = -1; String str = null; String address = s.getInetAddress().getHostAddress(); int port = s.getPort(); String host = "127.0.0.1"; Socket s2 = new Socket(host, 8888); OutputStream os = s2.getOutputStream(); Scanner sc = new Scanner(System.in); String str2 = null; while((length = is.read(b)) != -1){ str = new String(b, 0, length); System.out.println(address+":"+port+"\t"+str); str2 = sc.nextLine(); os.write(str2.getBytes()); if("886".equals(str2)){ break; } } os.close(); is.close(); ss.close(); } }
即是客户端也是服务器端之服务器端
修改后的代码:
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /* * 客户端发送"服务器端,你好啊"给服务器端。服务器端回应"客户端,你好啊"。 * 客户端:发送,接收数据。 * Socket */ public class ClientDemo5 { public static void main(String[] args) { Socket s = null; OutputStream os = null; InputStream is = null; try { s = new Socket("127.0.0.1", 9988); byte[] b = "服务器端,你好啊".getBytes(); // 获得输出流 os = s.getOutputStream(); os.write(b);// 发送数据。 // 由于需要接收数据,所以需要获得输入流。 is = s.getInputStream(); byte[] b2 = new byte[1024]; int length = is.read(b2); System.out.println(new String(b2, 0, length)); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { is.close(); os.close(); s.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
修改后的客户端
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo5 { public static void main(String[] args) { ServerSocket ss = null; Socket s = null; OutputStream os = null; try { ss = new ServerSocket(9988); ss.accept(); InputStream is = s.getInputStream(); byte[] b = new byte[1024]; int length = is.read(b); String str =new String(b, 0, length); // System.out.println(str); os = s.getOutputStream(); os.write(str.getBytes()); } catch (IOException e) { e.printStackTrace(); } finally{ try { os.close(); ss.close(); } catch (IOException e) { e.printStackTrace(); } } } }
修改后的服务器端
4:两两聊天。
客户端:一边接收消息,一边发送消息。一个线程负责接收消息,一个线程负责发送消息。
1 import java.io.IOException; 2 import java.io.InputStream; 3 import java.io.OutputStream; 4 import java.net.Socket; 5 import java.net.UnknownHostException; 6 import java.util.Scanner; 7 8 /* 9 * 两两聊天。客户端:一边接收消息,一边发送消息。 10 * 涉及到一边XXX一边XXX或者同时XXX的应该想到线程 11 * 一个线程负责接收消息,一个线程负责发送消息。 12 * (控制台实现) 13 */ 14 public class ClientDemo7 { 15 public static void main(String[] args) { 16 Socket s; 17 try { 18 String ip = "127.0.0.1"; 19 s = new Socket(ip, 9988); 20 //启动一个发送消息的线程 21 ClientSend send = new ClientSend(s); 22 send.start(); 23 //启动一个接收消息的线程 24 ClientReceice receice = new ClientReceice(s); 25 receice.start(); 26 } catch (UnknownHostException e) { 27 e.printStackTrace(); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 } 32 } 33 34 class ClientSend extends Thread{ 35 private Socket s; 36 public ClientSend(Socket s){ 37 this.s = s; 38 } 39 40 @Override 41 public void run() { 42 OutputStream os = null; 43 Scanner sc = new Scanner(System.in); 44 try { 45 os = s.getOutputStream(); 46 String str = null; 47 while(true){ 48 str = sc.nextLine(); 49 os.write(str.getBytes()); 50 os.flush(); 51 } 52 } catch (IOException e) { 53 e.printStackTrace(); 54 } 55 } 56 } 57 58 class ClientReceice extends Thread{ 59 private Socket s; 60 public ClientReceice(Socket s){ 61 this.s = s; 62 } 63 @Override 64 public void run() { 65 InputStream is = null; 66 try { 67 is = s.getInputStream(); 68 byte[] b = new byte[1024]; 69 int length = -1; 70 String str = null; 71 while((length = is.read(b)) != -1){ 72 str = new String(b, 0, length); 73 System.out.println("服务器端:"+str+"\r\n"); 74 } 75 } catch (IOException e) { 76 e.printStackTrace(); 77 } 78 } 79 }
客户端代码
1 import java.io.IOException; 2 import java.io.InputStream; 3 import java.io.OutputStream; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 import java.util.Scanner; 7 8 /* 9 * 两两聊天。客户端:一边接收消息,一边发送消息。 10 * 一个线程负责接收消息,一个线程负责发送消息。 11 */ 12 13 public class ServerDemo7 { 14 15 public static void main(String[] args) { 16 ServerSocket ss = null; 17 Socket s = null; 18 try { 19 ss = new ServerSocket(8888); 20 s = ss.accept(); 21 //开启一个发送消息的线程 22 ServerSend send = new ServerSend(s); 23 send.start(); 24 //开启一个接收消息的线程 25 ServerReceice receice = new ServerReceice(s); 26 receice.start(); 27 } catch (IOException e) { 28 e.printStackTrace(); 29 } 30 } 31 32 } 33 34 class ServerSend extends Thread{ 35 private Socket s; 36 public ServerSend(Socket s){ 37 this.s = s; 38 } 39 40 @Override 41 public void run() { 42 OutputStream os = null; 43 Scanner sc = new Scanner(System.in); 44 try { 45 os = s.getOutputStream(); 46 String str = null; 47 while(true){ 48 str = sc.nextLine(); 49 os.write(str.getBytes()); 50 os.flush(); 51 } 52 } catch (IOException e) { 53 e.printStackTrace(); 54 } 55 } 56 } 57 58 class ServerReceice extends Thread{ 59 private Socket s; 60 public ServerReceice(Socket s){ 61 this.s = s; 62 } 63 @Override 64 public void run() { 65 InputStream is = null; 66 try { 67 is = s.getInputStream(); 68 byte[] b = new byte[1024]; 69 int length = -1; 70 String str = null; 71 while((length = is.read(b)) != -1){ 72 str = new String(b, 0, length); 73 System.out.println("客户端:"+str); 74 } 75 } catch (IOException e) { 76 e.printStackTrace(); 77 } 78 } 79 }
服务器端代码