Java_基础—网络编程(TCP协议代码及其优化和服务器多线程优化)
TCP: 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据
1、客户端
- 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
- 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
- 输入流可以读取服务端输出流写出的数据
- 输出流可以写出数据到服务端的输入流
2、服务端
- 创建ServerSocket(需要指定端口号)
- 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
- 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
- 输入流可以读取客户端输出流写出的数据
- 输出流可以写出数据到客户端的输入流
Demo1_Client.java
package com.soar.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Demo1_Client {
/*
1.客户端
* 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
* 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
* 输入流可以读取服务端输出流写出的数据
* 输出流可以写出数据到服务端的输入流
*/
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 12345);
InputStream is = socket.getInputStream(); //获取客户端输入流
OutputStream os = socket.getOutputStream(); //获取客户端输出流
byte[] arr = new byte[1024];
int len = is.read(arr); //读取服务器发过来的数据
System.out.println(new String(arr,0,len)); //将数据转换为字符串并打印
os.write("学习使我快乐".getBytes()); //客户端向服务器写数据
socket.close(); //关掉客户端
}
}
Demo1_Server.java
package com.soar.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Demo1_Server {
/*
2.服务端
* 创建ServerSocket(需要指定端口号)
* 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
* 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
* 输入流可以读取客户端输出流写出的数据
* 输出流可以写出数据到客户端的输入流
*/
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(12345);
Socket socket = server.accept(); //接受客户端的请求
InputStream is = socket.getInputStream(); //获取客户端输入流
OutputStream os = socket.getOutputStream(); //获取客户端输出流
os.write("百度一下".getBytes()); //服务器向客户端写出数据
byte[] arr = new byte[1024];
int len = is.read(arr); //读取客户端发过来的数据
System.out.println(new String(arr,0,len)); //将数据转换为字符串并打印
socket.close();
//server.close(); //服务器一般不会关
}
}
将字节流包装成字符流的优化
注意:readLine()方法是以”/r/n”为判断结束标记的
Demo2_Client.java
package com.soar.tcp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Demo2_Client {
/*
1.客户端
*/
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 12345);
//将字节流包装成了字符流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//PrintStream中有写出换行的方法
PrintStream ps = new PrintStream(socket.getOutputStream());
System.out.println(br.readLine());
ps.println("你好,我是Soar_Sir的粉丝");
System.out.println(br.readLine());
ps.println("我超喜欢你");
socket.close(); //关掉客户端
}
}
Demo2_Server.java
package com.soar.tcp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Demo2_Server {
/*
2.服务端
*/
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(12345);
Socket socket = server.accept(); //接受客户端的请求
//将字节流包装成了字符流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//PrintStream中有写出换行的方法
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("欢迎咨询Soar_Sir");
System.out.println(br.readLine()); //readLine()方法是以"/r/n"为判断结束标记的
ps.println("谢谢");
System.out.println(br.readLine());
socket.close();
//server.close(); //服务器一般不会关
}
}
优化服务器,将服务器改为多线程的
package com.soar.tcp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Demo3_Server3 {
/*
2.服务端
*/
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(12345);
while(true){
//匿名内部类的变量需要用final来修饰
final Socket socket = server.accept(); //接受客户端的请求
new Thread(){
public void run(){
try {
//将字节流包装成了字符流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//PrintStream中有写出换行的方法
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("欢迎咨询Soar_Sir");
System.out.println(br.readLine()); //readLine()方法是以"/r/n"为判断结束标记的
ps.println("谢谢");
System.out.println(br.readLine());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
}