Java网络编程
1、寻找对方IP,通过端口号识别特定软件,通过协议来定义通讯规则。国际通用协议是TCP/IP,此协议既能用于局域网也能用于广域网。特定的组织或单位有自己的通讯协议,外界入侵是不行的,因为无法实现信息交互。
2、本地在未配置任何信息的时候默认的本地回环地址是127.0.0.1,这个地址的一个作用是可以测试本机网卡是否有问题,如果有问题是无法实现信息接收的。
3、局域网使用的保留地址是可以重复使用的,只是在连入外网的时候需要NAT转换。保留地址有三类:
A类:10.x.x.x
B类:172.16.x.x~172.31.x.x
C类:192.168.x.x
4、常见的端口:Web服务80,Web服务器8080,Mysql3306 。默认的端口可以更改。
5、TCP/IP参考模型是简化的OSI模型,它有四层:应用层、传输层、网际层、主机至网络层。Java网络编程在网际层和传输层之间。传输层是IP,网际层是TCP和UDP。
6、Java构造IP地址的类,将IP地址封装为对象。localhost是本地主机名,域名也是主机名,用来唯一标识主机。
7、IP地址查找:InetAddress对象
1 package test; 2 import java.net.*; 3 public class IP 4 { 5 public static void main(String[] args) throws UnknownHostException 6 { 7 // TODO Auto-generated method stub 8 //获取本地主机名和IP地址 9 InetAddress i=InetAddress.getLocalHost(); 10 System.out.println(i.toString()); 11 //获取主机 12 System.out.println(i.getHostName()); 13 //获取IP地址 14 System.out.println(i.getHostAddress()); 15 16 //查找任意IP地址下的主机名,如果为查到原样输出 17 InetAddress i1=InetAddress.getByName("172.18.163.11"); 18 //获取主机 19 System.out.println(i1.getHostName()); 20 //获取IP地址 21 System.out.println(i1.getHostAddress()); 22 23 //获取任意主机名的IP地址之获取百度主机地址 24 InetAddress i2=InetAddress.getByName("www.biadu.com"); 25 //获取主机 26 System.out.println(i2.getHostName()); 27 //获取IP地址 28 System.out.println(i2.getHostAddress()); 29 30 } 31 }
8、UDP是面向无连接的,有无连接都会发送信息包,是不可靠连接,对方是否收到也不知道,每个数据报的大小不超过64k,但速度快。聊天,网络视频就是UDP的。
9、TCP是面向连接的,建立连接,形成传输的通道,在连接中进行大数据量的传输,通过三次握手完成连接,保证对方在,是可靠协议。效率会稍低。下载是TCP的。
10、Java网络编程就是Socket编程。Socket类似于港口,插座,是计算机内的应用程序,其为网络服务提供一种机制,通过Socket这样的码头两台计算机才可以传输信息。简单地说,Socket是通信端点。
11、Socket端点有了后,就是传输协议,每一个传输协议都有自己建立Socket的方式。
12、UDP的Socket服务的建立,UDP发送端和接收端:
1 package test; 2 import java.net.*; 3 /* 4 * 需求:通过UDP传输方式,将一段文字数据发送出去(发送端代码) 5 * 思路: 6 * 1、建立UDPSocket服务; 7 * 2、提供数据,并将数据封装到数据包中; 8 * 3、通过Socket服务的发送功能,将数据包发送出去; 9 * 4、关闭资源。 10 */ 11 class UDPSend 12 { 13 public static void main(String[] args) throws Exception 14 { 15 //创建udp服务,通过DatagramSocket对象,同时指定发送端的端口号为1000 16 DatagramSocket ds=new DatagramSocket(1000); 17 18 //确定数据,并封装成数据包,制定发送到8888端口上 19 byte[] buf="joe shuie dsf ffdf".getBytes(); 20 DatagramPacket dp= 21 new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.32.4"),8888); 22 23 //通过Socket服务将已有的包发送出去,通过send方法 24 ds.send(dp); 25 26 //关闭资源 27 ds.close(); 28 } 29 } 30 /* 31 * 需求:定义一个应用程序,勇于接受UDP协议传输的数据并处理 32 * 33 * 思路: 34 * 1、定义UDPsocket服务,通常会监听一个端口,其实就是给这个接收网络应用程序一个数据标识,指定要处理的应用。 35 * 2、定义一个数据包,用于存储接收到的字节数据,数据包对象中可有提取数据的方法; 36 * 3、通过Socket服务的recieve方法将接收的数据存放到已经定义好的数据包中; 37 * 4、通过数据包对象的方法将不同的数据取出,打印在控制台上; 38 * 5、关闭资源。 39 */ 40 class UDPRecieve 41 { 42 public static void method() throws Exception 43 { 44 //创建udp Socket服务,建立端点,指定端口为8888 45 DatagramSocket ds=new DatagramSocket(8888); 46 47 //定义数据包用于存储数据 48 byte[] buf=new byte[1024]; 49 DatagramPacket dp=new DatagramPacket(buf,buf.length); 50 51 //通过服务的receive方法,将收到的数据存入到数据包中 52 ds.receive(dp); 53 54 //通过数据包的方法获取其中的数据 55 String ip=dp.getAddress().getHostAddress(); 56 String data=new String(dp.getData(),0,dp.getLength()); 57 int port=dp.getPort(); 58 System.out.println(ip+"::"+data+"::"+port); 59 60 //关闭资源 61 ds.close(); 62 } 63 }
13、UDP键盘录入
1 import java.net.*; 2 import java.io.*; 3 class UdpSend2 4 { 5 public static void main(String[] args) throws Exception 6 { 7 DatagramSocket ds = new DatagramSocket(); 8 9 BufferedReader bufr = 10 new BufferedReader(new InputStreamReader(System.in)); 11 12 String line = null; 13 14 while((line=bufr.readLine())!=null) 15 { 16 if("886".equals(line)) 17 break; 18 19 byte[] buf = line.getBytes(); 20 21 DatagramPacket dp = 22 new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10001); 23 24 ds.send(dp); 25 } 26 ds.close(); 27 } 28 } 29 30 31 32 class UdpRece2 33 { 34 public static void main(String[] args) throws Exception 35 { 36 DatagramSocket ds = new DatagramSocket(10001); 37 38 while(true) 39 { 40 byte[] buf = new byte[1024]; 41 DatagramPacket dp = new DatagramPacket(buf,buf.length); 42 43 ds.receive(dp); 44 45 String ip = dp.getAddress().getHostAddress(); 46 String data = new String(dp.getData(),0,dp.getLength()); 47 48 49 System.out.println(ip+"::"+data); 50 } 51 } 52 }
14、TCP并发上传图片
1 /* 2 客户端。 3 1,服务端点。 4 2,读取客户端已有的图片数据。 5 3,通过socket 输出流将数据发给服务端。 6 4,读取服务端反馈信息。 7 5,关闭。 8 9 */ 10 import java.io.*; 11 import java.net.*; 12 class PicClient 13 { 14 public static void main(String[] args)throws Exception 15 { 16 if(args.length!=1) 17 { 18 System.out.println("请选择一个jpg格式的图片"); 19 return ; 20 } 21 File file = new File(args[0]); 22 if(!(file.exists() && file.isFile())) 23 { 24 System.out.println("该文件有问题,要么补存在,要么不是文件"); 25 return ; 26 } 27 if(!file.getName().endsWith(".jpg")) 28 { 29 System.out.println("图片格式错误,请重新选择"); 30 return ; 31 } 32 if(file.length()>1024*1024*5) 33 { 34 System.out.println("文件过大,没安好心"); 35 return ; 36 } 37 Socket s = new Socket("192.168.1.254",10007); 38 FileInputStream fis = new FileInputStream(file); 39 OutputStream out = s.getOutputStream(); 40 byte[] buf = new byte[1024]; 41 int len = 0; 42 while((len=fis.read(buf))!=-1) 43 { 44 out.write(buf,0,len); 45 } 46 //告诉服务端数据已写完 47 s.shutdownOutput(); 48 InputStream in = s.getInputStream(); 49 byte[] bufIn = new byte[1024]; 50 int num = in.read(bufIn); 51 System.out.println(new String(bufIn,0,num)); 52 fis.close(); 53 s.close(); 54 } 55 } 56 57 /* 58 服务端 59 60 这个服务端有个局限性。当A客户端连接上以后。被服务端获取到。服务端执行具体流程。 61 这时B客户端连接,只有等待。 62 因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法。所以 63 暂时获取不到B客户端对象。 64 65 那么为了可以让多个客户端同时并发访问服务端。 66 那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。 67 68 如何定义线程呢? 69 70 只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。 71 */ 72 class PicThread implements Runnable 73 { 74 private Socket s; 75 PicThread(Socket s) 76 { 77 this.s = s; 78 } 79 public void run() 80 { 81 int count = 1; 82 String ip = s.getInetAddress().getHostAddress(); 83 try 84 { 85 System.out.println(ip+"....connected"); 86 InputStream in = s.getInputStream(); 87 File dir = new File("d:\\pic"); 88 File file = new File(dir,ip+"("+(count)+")"+".jpg"); 89 while(file.exists()) 90 file = new File(dir,ip+"("+(count++)+")"+".jpg"); 91 FileOutputStream fos = new FileOutputStream(file); 92 byte[] buf = new byte[1024]; 93 int len = 0; 94 while((len=in.read(buf))!=-1) 95 { 96 fos.write(buf,0,len); 97 } 98 OutputStream out = s.getOutputStream(); 99 out.write("上传成功".getBytes()); 100 fos.close(); 101 s.close(); 102 } 103 catch (Exception e) 104 { 105 throw new RuntimeException(ip+"上传失败"); 106 } 107 } 108 } 109 110 class PicServer 111 { 112 public static void main(String[] args) throws Exception 113 { 114 ServerSocket ss = new ServerSocket(10007); 115 116 while(true) 117 { 118 Socket s = ss.accept(); 119 120 new Thread(new PicThread(s)).start(); 121 122 123 } 124 125 //ss.close(); 126 } 127 }