第17章:网络编程

注:

  1. 网络编程(TCP/IP编程)!=网站编程
  2. 里面内容不做网络编程很难用到,如果需要时再看也可以,类似java的AWT和SWING编程
  3. 本文前半部分为马士兵课程中讲解内容,后半部分为疯狂java讲义中部分内容

一:网络基础

  1. 分层:应用–传输(udp/tcp)–网络(ip)–物理+数据链路
  2. 网络:tcp/ip详解
  3. ip协议:提供独一无二的ip地址
  4. udp/tcp协议:传输的方式
    1. tcp:可靠但是慢,先建立起连接才会继续进行,一定确保对方收到,也有序,先发的一定先到。例如银行取钱
    2. udp:说完就完事,不管对方的状态,不可靠但是快。例如qq聊天,游戏

二:TCP Socket(插座)编程

  1. 用来实现client–server的连接
  2. java.net包存有网络相关的类,包含Socket类和ServerSocket(TCP服务器端的插座,只用于实现TCP连接),因为UDP不分谁是server谁是client
  3. 端口号:用于表示是该ip上的,最多有65536个端口,最好用1024以上的端口,否则容易被系统占用,端口分为tcp端口和udp端口,每个都是65536个
  4. http默认端口80

三:TCP Socket通信

1.先起server再起client,server和client一起进行编写

package socket;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(6666);
		while(true){
			//accept和readline方法有点类似,为阻塞方法,如果没收到TCP请求	,就会一直堵塞
			Socket s = ss.accept();
			//用于接收client发送的消息
			DataInputStream dis = new DataInputStream(s.getInputStream());
			//readUTF也是阻塞的,但是这种效率太低,因为如果一个client如果没法东西过来,就会一直卡住,后面的client也发不过来消息
			System.out.println(dis.readUTF());
			System.out.println("建立连接");
			dis.close();
			s.close();
		}
		
	}
	
}

package socket;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {
	public static void main(String[] args) throws UnknownHostException, IOException {
		//client端随机生成一个端口号,指定该端口用于连接本机的6666端口
		Socket s = new Socket("127.0.0.1",6666);
		//client利用输出流来与server端沟通
		OutputStream os = s.getOutputStream();
		DataOutputStream dos = new DataOutputStream(os);
		dos.writeUTF("hello server!");
		dos.flush();
		dos.close();
		s.close();
	}
}

四:UDP编程

因为未建立虚拟链路,所以严格意义上没有server和client的概念

package udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class TestUDPClient {
	public static void main(String[] args) throws IOException {
		byte[] buf = (new String("Hello").getBytes());
		//DatagramPacket代表发送的数据报,被发送的地址在这里定义,而不是在Socket中定义
		DatagramPacket dp = new DatagramPacket(buf, buf.length,new //代表Socket
		InetSocketAddress("127.0.0.1",5678));
		DatagramSocket ds = new DatagramSocket(9999);
		ds.send(dp);
		ds.close();
	}
}

package udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TestUDPServer {
	public static void main(String[] args) throws IOException {
		byte buf[] = new byte[1024];
		//建立一个DatagramPacket用于接收client发来的数据
		DatagramPacket dp = new DatagramPacket(buf, buf.length);
		//起一个数据包socket在UDP的5678端口上
		DatagramSocket ds = new DatagramSocket(5678);
		while(true){
			//接收数据并放入DatagramPacket对象dp中,如果没收到内容,会阻塞
			ds.receive(dp);
			//dp.getLength():查看具体收了多少长度的数据
			System.out.println(new String(buf,0,dp.getLength()));
		}
	}
}

17.1 网络编程的基础知识

  1. IP协议:提供网间连接的完善功能,允许数据传输,但不保证可靠性。
  2. TCP协议:保证数据传输可靠性
  3. IP协议传输数据时,将数据分割为一个个小包,而TCP协议会在通信的两个实体上各建立一个Socket,一端发送,另一端收集这些数据包,并正确还原其顺序,TCP使用重发机制,A给B传输数据时,当某数据包没收到B"确认收到"反馈时,TCP协议会要求A重新发送,这就是所谓的可靠性
  4. 主机名:bigserver,域名:mycompany.com,那么全限定域名:bigserver.mycompany.com
17.1.1 IP地址和端口号
  1. IP地址用于唯一地标识网络上的一个通信实体,端口号标识该通讯实体上的唯一一个通信程序
  2. IP地址为4组8位二进制数组成,中间用原点隔开。端口号为0-65535

17.2 Java的基本网络支持

17.2.1 使用InetAddress
  1. InetAddress代表IP地址
import java.io.IOException;
import java.net.InetAddress;

public class InetAddressTest {
	public static void main(String[] args) throws IOException {
		//1. 通过主机名获得InetAddress对象
		InetAddress ip = InetAddress.getByName("www.baidu.com");
		//2. 判断是否可达
		System.out.println(ip.isReachable(2000));
		//3. 获取IP字符串:43.243.169.21
		System.out.println(ip.getHostAddress());
		//4. 根据原始地址127.0.0.1,获取InetAddress对象
		InetAddress local = InetAddress.getByAddress(new byte[]{127,0,0,1});
		System.out.println(local.isReachable(2000));
		//5.获取全限定域名(同时带有主机名和域名的名称):127.0.0.1
		System.out.println(local.getCanonicalHostName());
		//6.获取主机名
		System.out.println(local.getHostName());
	}
}

17.2.2 使用URLDecoder和URLEncoder
  1. URLDecoder和URLEncoder可以完成普通字符串与application/x-www-form-urlendcoded MIME字符串的相互转换
  2. 字符串中,西欧字符不转,转换中文字符时,首先看按哪种字符集进行转换,该字符集中如果一个中文占3个字节,由于每个字节又可以转换为2个16进制数,那么最终中文可以转为"%XX%XX%XX",X代表一个16进制数
  3. 当使用IE浏览器时,搜索中文,搜索栏中就会将中文转换成application/x-www-form-urlendcoded MIME字符串
    在这里插入图片描述

import java.net.*;

public class URLDecoderTest {
	public static void main(String[] args) throws Exception {
		// 1. 将application/x-www-form-urlencoded字符串转换成普通字符串
		// 其中的字符串是从IE浏览器复制过来的
		String keyWord = URLDecoder.decode("%E7%96%AF%E7%8B%82java", "utf-8");
		System.out.println(keyWord);
		// 2. 将普通字符串转换成application/x-www-form-urlencoded字符串
		String urlStr = URLEncoder.encode("疯狂Android讲义", "GBK");
		System.out.println(urlStr);
	}
}

发布了32 篇原创文章 · 获赞 0 · 访问量 941

猜你喜欢

转载自blog.csdn.net/hanzong110/article/details/102606232