Java之网络编程
Posted 我想回家
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之网络编程相关的知识,希望对你有一定的参考价值。
网络编程
概述
- 网络编程 : 通过编程实现不同计算机间数据的共享
- C/S : 客户端/服务器模式
- 好处:部分代码放在客户端,访问服务器只需要传输有效的数据.
- 弊端:必须安装客户端,并且服务器升级,对应的客户端必须升级.
- B/S : 浏览器/服务器模式
- 好处:不需要安装客户端,不需要考虑服务器升级问题.
- 弊端:所有的数据都在服务器,网络不好,反应慢,不友好.
网络编程三要素
- 协议 : 计算机与计算机之间传输的规则(协议的三要素如下)
- 语法,就是这一段内容要符合一定的规则和格式。例如,括号要成对,结束要使用分号等。
- 语义,就是这一段内容要代表某种意义。例如数字减去数字是有意义的,数字减去文本一般来说就没有意义。
- 顺序,就是先干啥,后干啥。例如,可以先加上某个数值,然后再减去某个数值。
- IP地址 : 在网络中,ip地址是唯一标识
- 端口号 : 计算机中应用程序的唯一标识
客户端的代码步骤
- 创建Socket的对象,指定ip地址和端口号
- 利用socket获取文件字节输出流对象(可以使用转换流将字节流转化为打印流)
- 利用字节流向服务端发送消息
- 关闭socket资源
服务端的代码步骤
- 创建ServerSocket对象,设置端口号
- 利用创建的ServerSocket对象使用sccept方法获取Socket对象
- 利用第二步获取的socket获取字节输入流对象(可以只用转换流将字节流转化为字符高效流)
- 使用第三步的流读取客户端发送的信息
- 关闭资源
在整个过程中,需要注意的是随时刷新缓冲区和关闭流,所以推荐使用打印流,会自动刷新和自动换行.
写个小例子,实现客户端和服务端的单次通信
package homework.demo5;
import java.io.*;
import java.net.Socket;
/**
* 创建客户端
*
* @author WZLOVE
* @create 2018-07-25 20:47
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建Socket对象
Socket socket = new Socket("localhost",8888);
// 利用转换流转换成打印流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);
// 向服务器写内容
pw.println("你好,我是客户端");
// 获取高效字符输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 获取服务器发送的消息
String s = br.readLine();
System.out.println("服务器说:" + s);
// 关闭流
socket.close();
}
}
package homework.demo5;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务端
*
* @author WZLOVE
* @create 2018-07-25 20:57
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务端网络对象,指定端口号
ServerSocket ss = new ServerSocket(8888);
// 获取Socket对象
Socket accept = ss.accept();
// 获取高效输入流
BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
// 获取输入的信息
String s = br.readLine();
System.out.println("客户端说 : " + s);
// 获取打印流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(accept.getOutputStream()),true );
// 向客户端发送消息
pw.println("你好,我是服务端");
// 关闭资源
accept.close();
ss.close();
}
}
写个例子,实现客户端向服务器上传图片
package homework.demo7;
import java.io.*;
import java.net.Socket;
/**
* 网络通信中的客户端
*/
public class Cilent {
public static void main(String[] args) throws IOException {
// 创建Socket客户端对象
Socket socket = new Socket("localhost",8888);
// 准备文件进行传输
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("yz.jpg"));
// 使用socket对象获取字节输入流对象
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
// 一边读文件,一边向服务器发送数据
byte[] arr = new byte[1024 * 5];
int len;
while((len = bis.read(arr)) != -1){
bos.write(arr,0,len);
}
// 数据上传完毕,刷新缓存区
bos.flush();
// 关闭不用的资源
bis.close();
// 关闭输出流套接字,这个步骤是必须的
socket.shutdownOutput();
// 读取反馈的数据
// 使用socket对象获取字节输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
StringBuilder sb = new StringBuilder();
while((line = br.readLine()) != null){
sb.append(line);
}
System.out.println(sb);
// 关闭资源
socket.close();
}
}
package homework.demo7;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务端
*/
public class Server {
public static void main(String[] args) throws IOException {
// 创建服务端的对象
ServerSocket ss = new ServerSocket(8888);
// 使用服务端对象获取Socket对象
Socket accept = ss.accept();
// 准备接受上传的文件并且写入服务器
// 创建高效字节输出流,用来指向文件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.jpg"));
// 使用socket对象获取文件字节输入流(转化为高效字节输入流)
BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
// 边读边写
byte[] arr = new byte[1024 * 5];
int len;
while((len = bis.read(arr)) != -1){
bos.write(arr,0,len);
// 进行刷新
bos.flush();
}
// 关闭不使用的资源
bos.close();
// 向客户端反馈信息
PrintWriter pw = new PrintWriter(new OutputStreamWriter(accept.getOutputStream()),true);
// 写信息
pw.println("上传成功");
// 关闭资源
accept.close();
ss.close();
}
}
有关网络的相关知识大家可以去订阅极客时间上的趣谈网络协议,那个讲的很清楚
以上是关于Java之网络编程的主要内容,如果未能解决你的问题,请参考以下文章
JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段