ip在java中 tcp tcp/ip协议java_System

  TCP/IP 模型。一组用于实现网络互连的通信协议,将协议分成四个层次。应用层、传输层、网络层、网络接口层。
  TCP,Transmission Control Protocol,传输控制协议。是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
  UDP,User Datagram Protocol,用户数据报协议。是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。
  IP协议,Internet Protocol Address,互联网协议地址/网际协议地址。分配给互联网设备的数字标签(唯一标识)。IP地址分为两种。IPV4,分成4段8位的二进制数;IPV6,分成8段十六进制数。
  Port,端口号。在通信实体上进行网络通讯的程序的唯一标识。

  InetAddress 类。

public class Test {

	public static void main(String[] args) throws UnknownHostException {
		// TODO Auto-generated method stub
		
		// 获得本地主机地址对象
		System.out.println(InetAddress.getLocalHost());
		
		// 根据主机名称获得地址对象
		System.out.println(InetAddress.getByName("baidu.com"));
		
		// 获得所有相关地址对象
		InetAddress[] all = InetAddress.getAllByName("baidu.com");
		
		for (InetAddress inetAddress : all) {
			System.out.println(inetAddress);
		}
		
		for (InetAddress inetAddress : all) {
			System.out.println("获取IP地址字符串 " + inetAddress.getHostAddress());
			// 获得IP地址主机名
			System.out.println("获取IP地址主机名 " + inetAddress.getHostName());
		}
	}
}

  基于TCP的网络编程,Socket编程。Socket(套接字)是网络中的一个通信节点。分为客户端 Socket 与服务器 ServerSocket。

  封装一个关闭流的通用方法。将 Closeable 接口作为泛型参数。

public class PublicMethod {

	public PublicMethod() {

	}

	public static void closeAll(Closeable... hh) {
		
		for (Closeable closeable : hh) {
			if (closeable != null) {
				try {
					closeable.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

  TCP 编程实现客户端发送数据给服务器端。

// 服务端
public class TestServer {

	public TestServer() {
		
	}

	public static void main(String[] args) throws IOException {

		ServerSocket ssocket = new ServerSocket(9527);
		// 与客户端建立连接
		Socket socket =  ssocket.accept();
		
		System.out.println("等待客户端输入");
		
		InputStream ins = socket.getInputStream();
		
		byte[] bt = new byte[1024];
		
		// 接收客户端发来的数据
		int len = ins.read(bt); // 阻塞,接收到数据才往下走
		System.out.println(new String(bt, 0, len));
		
		OutputStream ous = socket.getOutputStream();
		// 向客户端发送数据
		ous.write("不在。".getBytes());
		
		PublicMethod.closeAll(ous, ins, socket, ssocket);
	}
}
// 客户端
public class TestClient {

	public TestClient() {
	}

	public static void main(String[] args) throws UnknownHostException, IOException {
		
		// 本地 ip 用来测试
		Socket socket = new Socket("127.0.0.1", 9527);
		
		System.out.println("客户端已连接");
		
		OutputStream os = socket.getOutputStream();
		// 向服务端发送数据
		os.write("在吗?".getBytes());
		
		InputStream ins = socket.getInputStream();
		byte[] bt = new byte[1024];
		// 接收服务端发来的数据
		int len = ins.read(bt); // 阻塞,接收到数据才往下走
		System.out.println(new String(bt, 0, len));
			
		PublicMethod.closeAll(ins, os, socket);
	}
}

  TCP 编程实现客户端上传文件给服务器端。

public class TestServer {

	public TestServer() {
		
	}

	public static void main(String[] args) throws IOException {
		
		ServerSocket ssocket = new ServerSocket(8000);
		Socket socket = ssocket.accept();
		
		//输入流接收客户端数据
		InputStream ins = socket.getInputStream();
		
		// 随机文件名
		Double num = Math.random() * 1000000;
		String name = num.toString();
		
		// 输出流输出数据到文件
		OutputStream ous = new FileOutputStream("/Users/mac/Desktop/image备份/"+ name +".jpg");
		
		byte[] bt = new byte[1024];
		int len = ins.read(bt);
		
		while (len != -1) {
			ous.write(bt, 0, len);
			// 循环读取客户端数据, 阻塞,接收到数据才往下走
			len = ins.read(bt);
		}
		
		PublicMethod.closeAll(ous, ins, socket);
	}
}
public class TestClient {

	public TestClient() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) throws UnknownHostException, IOException {
		
		// 本地 ip 用来测试
		Socket socket = new Socket("127.0.0.1", 8000);
		
		// 输入流打开文件取数据
		InputStream ins = new FileInputStream("/Users/mac/Desktop/熊本熊/8ad0576698b03ee5014d880713d4d054.jpg");
		
		// 输出流向服务端发送输入流中取出的数据
		OutputStream ous = socket.getOutputStream();
		
		byte[] bt = new byte[1024];
		int len = ins.read(bt);
		while (len != -1) {
			// 循环向服务端发送数据
			ous.write(bt, 0, len);
			len = ins.read(bt);
		}
		
		PublicMethod.closeAll(ous, ins, socket);
	}
}

  TCP 实现多个客户端发送数据给服务器端。需要多线程,每连接一个客户端,开辟一个新线程。

// 自定义多线程
public class ServerThread extends Thread {

	private Socket s;
	
	public ServerThread() {
		
	}

	public ServerThread(Socket s) {
		super();
		this.s = s;
	}

	@Override
	public void run() {
		
		BufferedReader in = null;
		try {
			// 字符缓冲输入流接收客户端数据
			in = new BufferedReader(new InputStreamReader(s.getInputStream()));
			// 注意: 服务端循环是为了多个客户端连接,这里的循环是为了循环接收同一个客户端的多次输入
			while (true) {
				String hh = in.readLine();
				System.out.println(s.getInetAddress() + " 说 " +  hh);
				
				if (hh.equals("886")) {
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			PublicMethod.closeAll(in, s);
		}
		
	}
	
	public Socket getS() {
		return s;
	}
	
	public void setS(Socket s) {
		this.s = s;
	}
}
// 服务端
public class TestServer {

	public TestServer() {
		
	}

	public static void main(String[] args) throws IOException {

		ServerSocket ss = new ServerSocket(8000);
		
		// 死循环监听客户端,目的就是处理多个客户端的访问,需要有多个服务器连接
		while (true) {
			// 阻塞,连接后开辟线程
			Socket socket = ss.accept();
			// 自定义多线程接收 socket
			ServerThread st = new ServerThread(socket);
			st.start();
		}	
	}
}
// 客户端
public class TestClient {

	public TestClient() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) throws UnknownHostException, IOException {
				
		Socket s = new Socket("127.0.0.1", 8000);
		
		System.out.println("客户端已连接");
		
		Scanner input = new Scanner(System.in);
		
		// 字符缓冲输出流提升效率,桥接流连接字节流和字符流
		BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		
		while (true) {
			System.out.println("请输入:");
			String res = input.next();
			out.write(res);
			out.newLine();
			// 刷新字符从缓冲区到业务区
			out.flush();
			
			if (res.equals("886")) {
				break;
			}
		}
		
		PublicMethod.closeAll(out, s);
	}
}