zl程序教程

您现在的位置是:首页 >  后端

当前栏目

第84节:Java中的网络编程(中)

2023-09-11 14:16:53 时间

标题图

第84节:Java中的网络编程(中)

实现客户端和服务端的通信:

客户端需要的操作,创建socket,明确地址和端口,进行键盘录入,获取需要的数据,然后将录入的数据发送给服务端,为socket输出流,然后进行读取服务端发送回来的大写数据,为socket读取流,最后进行客户端显示器的显示,进行读写操作,关闭资源。

网络编程TCP客户端

package com.dashucoding.tcp3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TransClient {

	public static void main(String[] args) throws IOException {
		// 客户端
		// 创建socket 明确地址和端口
		Socket s = new Socket("192.168.1.151",10005);
		
		// 键盘录入
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		
		// 网络, socket输出流
//		OutputStream out = s.getOutputStream();
		
		// 传的是字符数据, 转换,提高效率
//		BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(out));
		
		// 打印流,既能接收字符又能接收字节
		PrintWriter out = new PrintWriter(s.getOutputStream());
		
		// 读取流,读取服务端发来的数据
//		InputStream in = s.getInputStream();
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		// 显示数据,使用输出语句
		
		// 频繁读写,读键盘
		String line = null;
		while((line=bufr.readLine()) != null) {
			if("over".equals(line)) {
				break;
			}
			// 读取键盘的数据发送到服务端
			out.println(line);
			
			// 读取服务端返回的数据
			String upperText = bufIn.readLine();
			System.out.println(upperText);
			
		}
		
		// 关闭资源
		s.close();
		
	}

}

对于服务端,要创建一个服务端的socket,然后明确端口,要读取客户端发送过来的数据,要读取socket输入流,接着使用socket输出流,将数据发送给客户端,进行读写操作,关闭资源。

网络编程TCP服务端

package com.dashucoding.tcp3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TransServer {

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

		System.out.println("服务端运行。。。");
		// 服务端:
		// 创建服务端的socket,明确端口
		ServerSocket ss = new ServerSocket(10005);

		while (true) {
			// 获取客户端对象

			Socket s = ss.accept();
			
			// 打印ip地址
			System.out.println(s.getInetAddress().getHostAddress()+"...connected");

			// socket输入流,读取客户端发过来的数据
			BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

			// socket输出流,将数据发送给客户端
//			PrintWriter out = new PrintWriter(s.getOutputStream());
			PrintWriter out = new PrintWriter(s.getOutputStream(), true);

			// 频繁的读写操作
			String line = null;
			while ((line = bufIn.readLine()) != null) {
				// 如果客户端发送过来的是over
				if ("over".equals(line)) {
					break;
				}
				
				// 客户端的数据
				System.out.println(line);
				// 字母转大写
				out.println(line.toUpperCase());
				// 都在缓冲区中,刷新
//				out.flush();
			}
			// 关闭客户端
			s.close();
		}
	}

}
package com.dashucoding.tcp3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TransClient {

	public static void main(String[] args) throws IOException {
		
		System.out.println("客户端运行。。。");
		// 客户端
		// 创建socket 明确地址和端口
		Socket s = new Socket("192.168.2.151",10005);
		
		// 键盘录入
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		
		// 网络, socket输出流
//		OutputStream out = s.getOutputStream();
		
		// 传的是字符数据, 转换,提高效率
//		BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(out));
		
		// 打印流,既能接收字符又能接收字节
//		PrintWriter out = new PrintWriter(s.getOutputStream());
		PrintWriter out = new PrintWriter(s.getOutputStream(), true);
		
		// 读取流,读取服务端发来的数据
//		InputStream in = s.getInputStream();
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		// 显示数据,使用输出语句
		
		// 频繁读写,读键盘
		String line = null;
		// 都一行,有行终止符才返回
		while((line=bufr.readLine()) != null) {
			// 读取键盘的数据发送到服务端
//			out.print(line+"\r\n");
			out.println(line);
			// 刷数据,都在缓冲区中
//			out.flush();
			if("over".equals(line)) {
				break;
			}
			
			// 读取服务端返回的数据
			String upperText = bufIn.readLine();
			System.out.println(upperText);
			
		}
		
		// 关闭资源
		s.close();
		
	}

}

上传文件

void shutdownInput() 此套接字的输入流置于“流的末尾”
void shutdownOutput() 禁用此套接字的输出流
String toString() 将此套接字转换为String.

客户端:

package com.dashucoding.net.uploadtext;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadTextClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("上传文件客户端运行。。。");
		// 客户端
		// 创建socket 明确地址和端口
		Socket s = new Socket("192.168.43.126", 10006);

		// 读取文本文件
		BufferedReader bufr = new BufferedReader(new FileReader("tempfile\\client.txt"));
		// 将数据发送给服务端
		PrintWriter out = new PrintWriter(s.getOutputStream(), true);
		
		
		// 显示数据,使用输出语句

		// 频繁读写,读键盘
		String line = null;
		// 都一行,有行终止符才返回true
		while ((line = bufr.readLine()) != null) {
			
			out.println(line);

		}
		
		// 给服务端发送一个结束标记,条约标记
//		out.println("over");
		s.shutdownOutput();
		// 向服务端发送了结束标记
		
		// 读取流,读取服务端发来的数据
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String info = bufIn.readLine();
		System.out.println(info);
		// 关闭资源
		bufr.close();
		s.close();
	}

}

服务端:

package com.dashucoding.net.uploadtext;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class UploadTextServer {

	public static void main(String[] args) throws IOException {
		System.out.println("上传文本服务端运行。。。");
		// 服务端:
		// 创建服务端的socket,明确端口
		ServerSocket ss = new ServerSocket(10006);

		while (true) {
			// 获取客户端对象

			Socket s = ss.accept();
			System.out.println(s.getInetAddress().getHostAddress() + "...connected");

			// socket输入流,读取客户端发过来的数据
			BufferedReader bufIn = new BufferedReader(new InputStreamReader(
					s.getInputStream()));

			// socket输出流,目的是文件
			PrintWriter pw = new PrintWriter(new FileWriter("tempfile\\server.txt"), true);

			// 频繁的读写操作
			String line = null;
			while ((line = bufIn.readLine()) != null) {
				if("over".equals(line)) {
					break;
				}
				
				pw.println(line);
			}
			
			// 发回给客户端,上传成功
			PrintWriter out = new PrintWriter(s.getOutputStream(),true);
			out.println("上传成功");
			
			// 关闭客户端
			s.close();
		}
	}

}

上传图片

客户端:

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadPicClient {

	public static void main(String[] args) throws IOException {
		
		System.out.println("上传图片客户端运行。。。");
		// 上传图片
		// 创建socket
		Socket s = new Socket("192.168.43.126",10007);
		
		// 读取图片,图片路径
		File picFile = new File("tempfile\\001.jpg");
		FileInputStream fis = new FileInputStream(picFile);
		
		// socket 输出流
		OutputStream out = s.getOutputStream();
		
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=fis.read(buf)) != -1) {
			out.write(buf,0,len);
		}
		
		// 告诉服务器端图片数据发送完毕,不要等着读了。
		s.shutdownOutput();
		
		// 读取上传成功
		InputStream in = s.getInputStream();
		byte[] bufIn = new byte[1024];
		int lenIn = in.read(bufIn);
		System.out.println(new String(bufIn, 0, lenIn));
		
		// 关闭
		fis.close();
		s.close();
		
	}

}

服务端:

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.CORBA_2_3.portable.OutputStream;

public class UploadPicServer {

	public static void main(String[] args) throws IOException {
		
		
		System.out.println("上传图片服务端运行。。。");
		// 创建serversocket
		ServerSocket ss = new ServerSocket(10007);

		while (true) { // 实现上传多回
			// 获取客户端
			Socket s = ss.accept();
			String ip = s.getInetAddress().getHostAddress();
			System.out.println(ip+"...connected");

			// 读取图片数据
			InputStream in = s.getInputStream();

			// 写图片数据到文件
			File picFile = new File("tempfile\\server.jpg"); // 存储图片
			FileOutputStream fos = new FileOutputStream(picFile);

			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = in.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}

			// 给客户端返回一个回馈信息
			java.io.OutputStream out = s.getOutputStream();
			out.write("上传成功".getBytes());

			// 关闭资源
			fos.close();
			s.close();
		}
	}

}

如何解决图片重名的问题:

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadPicClient {

	public static void main(String[] args) throws IOException {
		
		System.out.println("上传图片客户端运行。。。");
		// 上传图片
		// 创建socket
		Socket s = new Socket("192.168",10007);
		
		// 读取图片,图片路径
		File picFile = new File("tempfile\\001.jpg");
		FileInputStream fis = new FileInputStream(picFile);
		
		// socket 输出流
		OutputStream out = s.getOutputStream();
		
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=fis.read(buf)) != -1) {
			out.write(buf,0,len);
		}
		
		// 告诉服务器端图片数据发送完毕,不要等着读了。
		s.shutdownOutput();
		
		// 读取上传成功
		InputStream in = s.getInputStream();
		byte[] bufIn = new byte[1024];
		int lenIn = in.read(bufIn);
		System.out.println(new String(bufIn, 0, lenIn));
		
		// 关闭
		fis.close();
		s.close();
		
	}

}
package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.CORBA_2_3.portable.OutputStream;

public class UploadPicServer {

	public static void main(String[] args) throws IOException {
		
		
		System.out.println("上传图片服务端运行。。。");
		// 创建serversocket
		ServerSocket ss = new ServerSocket(10007);

		while (true) { // 实现上传多回
			// 获取客户端
			Socket s = ss.accept();
			String ip = s.getInetAddress().getHostAddress();
			System.out.println(ip+"...connected");

			// 读取图片数据
			InputStream in = s.getInputStream();

			// 写图片数据到文件
			// 创建目录
			File dir = new File("e:\\uploadpic");
			// 如果不存在就创建目录
			if(!dir.exists()) {
				dir.mkdir();
			}
			// 给文件编号
			// 加计数器
			int count = 1;
			// 防止第二次为0
			File picFile = new File(dir, ip + "("+count+").jpg");
//			if(picFile.exists()) {
			while(picFile.exists()) {
				count++;
				picFile = new File(dir, ip + "("+count+").jpg");
			}
			FileOutputStream fos = new FileOutputStream(picFile);
			
//			File picFile = new File("tempfile\\" + ip + ".jpg");
//			File picFile = new File("tempfile\\server.jpg"); 
			// 存储图片
			

			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = in.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}

			// 给客户端返回一个回馈信息
			java.io.OutputStream out = s.getOutputStream();
			out.write("上传成功".getBytes());

			// 关闭资源
			fos.close();
			s.close();
		}
	}

}

解决上传并发的问题

结构

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadPicClient {

	public static void main(String[] args) throws IOException {
		
		System.out.println("上传图片客户端运行。。。");
		// 上传图片
		// 创建socket
		Socket s = new Socket("",10007);
		
		// 读取图片,图片路径
		File picFile = new File("tempfile\\001.jpg");
		FileInputStream fis = new FileInputStream(picFile);
		
		// socket 输出流
		OutputStream out = s.getOutputStream();
		
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=fis.read(buf)) != -1) {
			out.write(buf,0,len);
		}
		
		// 告诉服务器端图片数据发送完毕,不要等着读了。
		s.shutdownOutput();
		
		// 读取上传成功
		InputStream in = s.getInputStream();
		byte[] bufIn = new byte[1024];
		int lenIn = in.read(bufIn);
		System.out.println(new String(bufIn, 0, lenIn));
		
		// 关闭
		fis.close();
		s.close();
		
	}

}
package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.CORBA_2_3.portable.OutputStream;

public class UploadPicServer {

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

		System.out.println("上传图片服务端运行。。。");
		// 创建serversocket
		ServerSocket ss = new ServerSocket(10007);

		while (true) { // 实现上传多回
			// 获取客户端
			Socket s = ss.accept();

			new Thread(new UploadPic(s)).start();
		}
	}

}
package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

// 创建任务
// 线程完成任务后,会自动结束
public class UploadPic implements Runnable {

	private Socket s;

	// 创建构造函数
	public UploadPic(Socket s) {
		this.s = s;
	}

	@Override
	public void run() {
		try {
			// 主线程负债接收客户端,其它线程负责接收数据

			String ip = s.getInetAddress().getHostAddress();
			System.out.println(ip + "...connected");

			// 读取图片数据
			InputStream in = s.getInputStream();

			// 写图片数据到文件
			// 创建目录
			File dir = new File("e:\\uploadpic");
			// 如果不存在就创建目录
			if (!dir.exists()) {
				dir.mkdir();
			}
			// 给文件编号
			// 加计数器
			int count = 1;
			// 防止第二次为0
			File picFile = new File(dir, ip + "(" + count + ").jpg");
//						if(picFile.exists()) {
			while (picFile.exists()) {
				count++;
				picFile = new File(dir, ip + "(" + count + ").jpg");
			}
			FileOutputStream fos = new FileOutputStream(picFile);

			// 开始循环进行读写操作
			// 一个线程,不能处理并发的数据
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = in.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}

			// 给客户端返回一个回馈信息
			java.io.OutputStream out = s.getOutputStream();
			out.write("上传成功".getBytes());

			// 关闭资源
			fos.close();
			s.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

客户端:浏览器,服务端:Tomcat

端口号,\con\server.xml

效果

浏览器发送HTTP请求

GET / HTTP / 1.1
Accept: 
Accept-Language:
Accept-Encoding:
User-Agent:
Host:
Connection:

请求行,协议,应用层协议,超文本传输协议,请求方式,访问资源的路径,http的协议版本,

效果

package com.dashucoding.net.myserver;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class MyBrowser {

	public static void main(String[] args) throws UnknownHostException, IOException {
		// 浏览器发送http消息
		Socket s = new Socket("",8080);
		
		// 把信息发送给服务端
		PrintWriter out=new PrintWriter(s.getOutputStream(),true);
		out.println("");
		out.println();//空行
		
		// 读取服务端的数据
		InputStream in = s.getInputStream();
		byte[] buf = new byte[1024];
		String text = new String(buf,0,len);
		System.out.print(text);

		s.close();
	}

}

发送和http协议相同的信息,收到了Tomcat服务器返回的数据。

版本

插件

package com.dashucoding.net.myserver;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class MyBrowserGui extends JFrame {

	private JPanel contentPane;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MyBrowserGui frame = new MyBrowserGui();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MyBrowserGui() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
	}

}

下载插件

url的描述

java.net
类 url
java.lang.object
java.net.url
所有已实现的接口:
serializable

public final class url extends object implements serializable

url 表示一个统一的资源定位符,用于指向互联网"资源"的指针。
// 构造方法
url (string spec):
根据string表示形式创建url对象

url (string protocol, string host, int port, string file)
根据指定protocol,host,port号和file创建url对象
package com.dashucoding.net.url;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class URLDemo {

	public static void main(String[] args) throws IOException {
		
String str_url = "http://";
		
		//将url地址封装成对象。
		URL url = new URL(str_url);
		
//		System.out.println("getProtocol:"+url.getProtocol());
//		System.out.println("getHost:"+url.getHost());
//		System.out.println("getPort:"+url.getPort());
//		System.out.println("getPath:"+url.getPath());
//		System.out.println("getFile:"+url.getFile());
//		System.out.println("getQuery:"+url.getQuery());
		
		//获取指定资源的连接对象,封装了socket。
		URLConnection conn = url.openConnection();
		
//		System.out.println(conn);
		
		InputStream in = conn.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String text = new String(buf,0,len);
		System.out.println(text);
		
		
	}

}
openConnection
public URLConnection openConnection() throws IOException
返回一个URLConnection对象,它表示到url所引用的远程对象的连接

urlconnection

图片

package com.dashucoding.net.url;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class URLDemo {

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

		String str_url = "http://";

		// 将url地址封装成对象。
		URL url = new URL(str_url);

//		System.out.println("getProtocol:"+url.getProtocol());
//		System.out.println("getHost:"+url.getHost());
//		System.out.println("getPort:"+url.getPort());
//		System.out.println("getPath:"+url.getPath());
//		System.out.println("getFile:"+url.getFile());
//		System.out.println("getQuery:"+url.getQuery());

		// 获取指定资源的连接对象,封装了socket。
		URLConnection conn = url.openConnection();

//		System.out.println(conn);

		InputStream in = conn.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String text = new String(buf, 0, len);
		System.out.println(text);

	}

}

网络编程中HTTP版本的区别

http1.0请求一次连接就断开了,一次连接只能有一次请求,http1.1一次连接多次请求。

URL用于解析url地址,URLConnection用于获取url的连接。

常见的网络架构:cs和bs

client / server
客户端和服务端,维护麻烦

browser / server
只需要服务端,只要系统内置浏览器
所有的运算在服务端,简单易用

结言

好了,欢迎在留言区留言,与大家分享你的经验和心得。

感谢你学习今天的内容,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友,感谢。

达叔小生:往后余生,唯独有你
You and me, we are family !
90后帅气小伙,良好的开发习惯;独立思考的能力;主动并且善于沟通
简书博客: 达叔小生
https://www.jianshu.com/u/c785ece603d1

结语

  • 下面我将继续对 其他知识 深入讲解 ,有兴趣可以继续关注
  • 小礼物走一走 or 点赞