javaEE(网络编程、TCP、线程池优化)
作者:互联网
网络编程
- Client-Server(CS)
- Browser/Server(BS)
1.客户端--服务端
安装客户端
- 更新。
- 依赖PC
2.浏览器和服务端
- 分布式
- 兼容性
- 一站开发
网络通信:
- UDP 不确定在线 不做消息确认
- TCP可靠的通信
- 及时通信
- 模拟BS通信
三要素
- IP地址:设备在网络中的地址,唯一标识
- 端口:应用程序在设备中的唯一标识
- 协议:数据在网络中的传输规则,常见的有UDP协议和TCP协议
IPv4:
- 32位(4字节)
- 点分十进制
IPv6:
- 128位(16个字节),号称可以为地球上的每一粒沙子编号
- 冒分十六进制
域名
- 公网地址、私网地址(局域网使用)
- 192.168..开头就是局域网 192.168.0.0--192.168.255.255,专门内部使用
Ip命令:
- ipcofig:查看本机ip
- ping IP的地址:检查网络是否连通
特殊id:
- 127.0.0.1或者localhost:只会找本机
Ip地址操作类
InetAddress
- public static InetAddress getLocalHost() 返回主机的ip
- public static InetAddress getByName()得到指定的主机ip地址对象,参数是域名或者ip地址
- public String getHostName()获取此ip地址的主机名
- public String getHostAddress()返回ip地址的主机名
- public boolean isReachable(int timeout)在毫秒内连通该ip地址对应的主机,连通返回true
main(){
//1.获得本机ip对象
InetAddress ip = InetAddress .getLocalHost();
//得到域名
InetAddress ip = InetAddress .getByName("www.baidu.com");
//公网的ip
InetAddress ip = InetAddress .getByName("112.82.248.76");
端口
标识在计算机上运行的程序,规定的是一个16的二进制,0-65535.
端口类型:
- 周至端口:0-1023(HTTP:80,FTP:21)
- 注册端口:1024-49151(Tomcat:8080,MySQL:3306)
- 动态端口:49152-65535
协议
连接和通讯数据的规则--------网络通讯协议
- OSI参考模型:世界互联网协议规范
- TCP/IP参考模型:事实的国际标准
TCP:
- 应用层
- HTTP\FTP\DNS\SMTP
- 传输层
- TCP\UDP
- 网路层
- IP\ICMP
- 数据链路层+物理
- 物理寻址、比较流
传输层的协议:
- TCP:传输控制协议
- UCP:用户数据报协议
TCP:
- 采用TCP协议,必须双方先建立连接,它使面向连接的可靠通信协议
- 传输前,采用三次握手方式建立连接,所以是可靠的
- 在连接中可以进行大数据量的传输
- 连接、发送数据都需要确认、且传输完毕后、还要释放已建立的连接。通信效率较低
TCP协议的场景:
- 对信息安全要求较高的场景,文件下载,金融数据通信
TCP的三次握手
- 客户端向服务器发送请求--等待服务器确认
- 服务器向客户端返回了一个相应--告诉客户端接受到了请求
- 客户端向服务器再次发出确认信息---连接建立
TCP的四次挥手
- 客户端向服务器发出取消请求
- 服务器向客户端返回一个相应---表示收到客户端取消请求
- 服务器向客户端发出确认消息
- 客户端再次发出消息--连接取消
UDP:
- 一中无连接、不可靠的传输协议
- 将数据源ip、目的地ip、和端口封装成数据包、不需要建立连接
- 每个数据包的大小限制在64kb内
- 发送不管对方是否准备好,接收方也不确认,所以是不可靠的
- 可以发送广播、发送数据结束时无需释放资源、开销小、速度快
适合语音通话、视频会话
UDP
数据包:
构造器:
- public DatagramPacket(byte[] buf,int length, InetAddress,int port)port接受的端口
- public DatagramPacket(byte[] buf,int length) 创建接受端的数据包 buf储存的内容 length 能接受的长度
DatagramSocket发送端和接收端对象
构造器:
- public DatagramSocket()
- public DatagramSocket(int port)
方法:
- public void send( DatagramPacket dp) 发送数据包
- public void receive( DatagramPacket p)接收数据包
main(){
DatagramSocket sock =new DatagramSocket();
//数据包
byte[] buffer ="我是韭菜".getBytes();
DatagramPacket packet =new DatagramPacket(buffer,buffer.length,InetAddress.getLocalHost(),8888);
sock.send(packet);
sock.close();
}
main(){
DatagramSocket sock =new DatagramSocket(8888);
//数据包
byte[] buffer =new byte[1024*64];
DatagramPacket packet =new DatagramPacket(buffer,buffer.length);
sock.receive(packet);
String s =new String(buffer);
socket.close();
}
多发多收
以后吧累了
TCP
面向连接,安全,可靠
java.net.Socket
Socket:
- public Socket(String host,int port) 创建Socket对象与服务器连接,参数为服务器的ip和端口
方法:
- OutputStream getOutputStream()获得字节输出流
- InputStream getInputStream() 获得字节输入流
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
//发送消息
ps.print("约么");
ps.flush();
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
Socket socket =ss.accept();
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms)
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
多发多收
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
Socket socket =ss.accept();
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
但是服务daunt不可以接受多个客户端信息。
多客户端
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
//收消息
while(ms=br.readLine()!=null){
Socket socket =ss.accept();
new SerberThread(socket).start();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
线程:
public class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket-socket;
}
@Override
public void run(){
try{
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
}
//socket.close();不建议关闭流
}catch{
e.printStrackTrace();
}
}
}
线程池优化
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
//定义线程池
private Static ExecutorService pool =new ThreadPoolExecutor(3,5,6,TimeUnit.SECONDS,new ArrayBlockingQueue(2,Executor.defaultThreadFactorty(),new ThreadPoolExcutor.AbortPolicy()));
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
//收消息
while(ms=br.readLine()!=null){
Socket socket =ss.accept();
Runner a =new SerberThread(socket);
pool.excute(a);
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
线程:
public class ServerThread implement Runnable{
private Socket socket;
public ServerThread(Socket socket){
this.socket-socket;
}
@Override
public void run(){
try{
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
}
//socket.close();不建议关闭流
}catch{
e.printStrackTrace();
}
}
}
优点:
- 适合通信时长较短的案例
即时通讯
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//创建一个读线程
new ClienThread(socket).start();
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
-
客户端的线程
public class ClienrThread implement Runnable{ private Socket socket; public ClienThread(Socket socket){ this.socket-socket; } @Override public void run(){ try{ //得到字节输出流 getInputStream is =socket.getInputStream(); //变成高级流 BufferedReader br =new BufferedReader(new InputStreamReader(is)); //收消息 String line; while(line=br.readLine()!=null){ System.out.print(socket.RemoteSocketAddress()+"说了"+line); } //socket.close();不建议关闭流 }catch{ e.printStrackTrace(); } } }
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
//定义线程池
private Static ExecutorService pool =new ThreadPoolExecutor(3,5,6,TimeUnit.SECONDS,new ArrayBlockingQueue(2,Executor.defaultThreadFactorty(),new ThreadPoolExcutor.AbortPolicy()));
//客户端的留言
public static List<Socket> allSocket = new ArrayList<>();
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
//收消息
while(ms=br.readLine()!=null){
Socket socket =ss.accept();
allStock.add(socket);
Runner a =new SerberThread(socket);
pool.excute(a);
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
线程:
public class ServerThread implement Runnable{
private Socket socket;
public ServerThread(Socket socket){
this.socket-socket;
}
@Override
public void run(){
try{
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
sendMssageToAll(line);
}
//socket.close();不建议关闭流
}catch{
e.printStrackTrace();
}
}
private void sendMssageToAll(String msg){
for(Socket socket:ServlerThread.allSocket){
PrintStream ps =new PrintStream(socket.getOutputStream());
ps.println(msg);
ps.flush();
}
}
}
标签:Socket,javaEE,TCP,ServerSocket,线程,ms,new,public,socket 来源: https://www.cnblogs.com/HJZ114152/p/16406716.html