网络编程Socket_ServerSocket
软件结构
C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件;
B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等;
两种架构各有优势 ,但是都离不开网络编程;
网络通信:
网络通信协议:计算机必须穿遵循规则才能进行之间的通信;
TCP/IP协议:传输控制协议因特网互联协议( Transmission Control Protocol/Internet Protocol),是
Internet最基本、最广泛的协议
TCP:面向连接(既需要三次握手);传输不会丢失数据;
UDP:不面向连接(不需要三次握手);传输会丢失数据;
网络编程三要素:IP+协议+端口
端口号:取值范围是0~65535,其中,0~1023之间的端口号用于一些知名的网络服务和应用
TCP通信程序
TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client)与服务端(Server)
1. 服务端程序,需要事先启动,等待客户端的连接
2. 客户端主动连接服务器端,连接成功才能通信。服务端不可以主动连接客户端
JAVA中提供了两个类Socket,ServerSocket实现通信程序;
Socket类
public Socket(String host, int port) :创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null ,则相当于指定地址为回送地址
public InputStream getInputStream() 返回此套接字的输入流;
public OutputStream getOutputStream() 返回此套接字的输出流;
public void close() 关闭此套接字
public void shutdownOutput() 禁用此套接字的输出流
ServerSocket类
public ServerSocket(int port) 使用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指定的端口号上,参数port就是端口号
public Socket accept() 侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法会一直阻塞直到建立连接
客户端文件上传,服务端文件保存案列
优化思路:
1,图片文件名称写死的问题,可以使用时间戳解决;
2,循环接受,服务端可以一直接受客服端请求;
3,效率问题,可以匿名线程,多少个请求就开多少个线程;
客户端
public class FileUpload_Client {
public static void main(String[] args) throws IOException {
// 1.创建流对象
// 1.1 创建输入流,读取本地文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg"));
// 1.2 创建输出流,写到服务端
Socket socket = new Socket("localhost", 6666);
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
//2.写出数据.
byte[] b = new byte[1024 * 8 ];
int len ;
while (( len = bis.read(b))!=‐1) {
bos.write(b, 0, len);
}
// 关闭输出流,通知服务端,写出数据完毕
socket.shutdownOutput();
System.out.println("文件发送完毕");
// 3. =====解析回写============
InputStream in = socket.getInputStream();
byte[] back = new byte[20];
in.read(back);
System.out.println(new String(back));
in.close();
// ============================
// 4.释放资源
socket.close();
bis.close();
}
}
服务端
public class FileUpload_Server {
public static void main(String[] args) throws IOException {
System.out.println("服务器 启动..... ");
// 1. 创建服务端ServerSocket
ServerSocket serverSocket = new ServerSocket(6666);
// 2. 循环接收,建立连接
while (true) {
Socket accept = serverSocket.accept();
/*
3. socket对象交给子线程处理,进行读写操作
Runnable接口中,只有一个run方法,使用lambda表达式简化格式
*/
new Thread(() ‐> {
try (
//3.1 获取输入流对象
BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
//3.2 创建输出流对象, 保存到本地 .
FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() +
".jpg");
BufferedOutputStream bos = new BufferedOutputStream(fis);
) {
// 3.3 读写数据
byte[] b = new byte[1024 * 8];
int len;
while ((len = bis.read(b)) != ‐1) {
bos.write(b, 0, len);
}
// 4.=======信息回写===========================
System.out.println("back ........");
OutputStream out = accept.getOutputStream();
out.write("上传成功".getBytes());
out.close();
//================================
//5. 关闭 资源
bos.close();
bis.close();
accept.close();
System.out.println("文件上传已保存");
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
}
模拟B\S服务器
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8888);
while(true){
Socket socket = server.accept();
new Thread(new Web(socket)).start();
}
}
static class Web implements Runnable{
private Socket socket;
public Web(Socket socket){
this.socket=socket;
}
public void run() {
try{
//转换流,读取浏览器请求第一行
BufferedReader readWb = new
BufferedReader(new InputStreamReader(socket.getInputStream()));
String requst = readWb.readLine();
//取出请求资源的路径
String[] strArr = requst.split(" ");
System.out.println(Arrays.toString(strArr));
String path = strArr[1].substring(1);
System.out.println(path);
FileInputStream fis = new FileInputStream(path);
System.out.println(fis);
byte[] bytes= new byte[1024];
int len = 0 ;
//向浏览器 回写数据
OutputStream out = socket.getOutputStream();
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Content‐Type:text/html\r\n".getBytes());
out.write("\r\n".getBytes());
while((len = fis.read(bytes))!=‐1){
out.write(bytes,0,len);
}
fis.close();
out.close();
readWb.close();
socket.close();
}catch(Exception ex){
}
}
}
}