本文共 4146 字,大约阅读时间需要 13 分钟。
服务器端:
package com.imooc;import java.io.IOException;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;/* * 服务器端 */public class Server { public static void main(String[] args) { try { //1.创建服务器端socket。即ServerSocket,指定绑定的端口,并监听此端口 ServerSocket serverSocket = new ServerSocket(8888); Socket socket=null; //记录客户端请求数 int count = 0; System.out.println("***服务器即将启动,等待客户端的连接***"); //循环监听等待客户端连接 while(true) { //调用accept()方法开始监听,等待客户端的连接 socket = serverSocket.accept(); //创建一个新的线程 ServerThread serverThread = new ServerThread(socket); //启动线程 serverThread.start(); count++;//统计客户端数量 System.out.println("客户端数量:"+count); InetAddress address = socket.getInetAddress(); System.out.println("当前客户端的IP:"+address.getHostAddress()); } } catch (IOException e) { e.printStackTrace(); } }}
服务器线程类:
package com.imooc;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.Socket;/* * 服务器端线程处理类 */public class ServerThread extends Thread { //和本线程相关的Socket Socket socket = null; public ServerThread(Socket socket) { this.socket=socket; } //线程执行的操作,响应客户端的请求 public void run() { InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; OutputStream os = null; PrintWriter pw = null; try { is = socket.getInputStream();//字节输入流 isr = new InputStreamReader(is);//将字节流转换为字符流提高性能 br = new BufferedReader(isr); String info = null; while((info=br.readLine())!=null) { System.out.println("我是服务器,客户端说:"+info); } socket.shutdownInput(); //获取输出流,响应客户端请求 os = socket.getOutputStream(); pw = new PrintWriter(os); pw.write("欢迎您!"); pw.flush();//刷新缓存 socket.shutdownOutput(); }catch(IOException e) { e.printStackTrace(); }finally { try { //关闭相关资源 if (pw != null) pw.close(); if (os != null) os.close(); if (br != null) br.close(); if (isr != null) isr.close(); if (is != null) is.close(); if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } }}
客户端:
package com.imooc;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;/* * 基于TCP协议的Socket通信,实现用户登录 * 客户端 */public class Client { public static void main(String[] args) { try { //1.创建客户端Socket,指定服务器地址和端口 Socket socket = new Socket("localhost",8888); //2.获取输出流。想服务端发送信息 OutputStream os = socket.getOutputStream();//字节输出流 PrintWriter pw = new PrintWriter(os);//将输出流包装成打印流 pw.write("用户名:tom;密码:456"); pw.flush(); socket.shutdownOutput(); //3.获取输入流,读取服务端响应 InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String info = null; while((info=br.readLine())!=null) { System.out.println("我是客户端,服务端说:"+info); } socket.shutdownInput(); //4.关闭资源 br.close(); is.close(); pw.close(); os.close(); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}
运行结果:
服务器端:
***服务器即将启动,等待客户端的连接***客户端数量:1当前客户端的IP:127.0.0.1我是服务器,客户端说:用户名:admin;密码:123客户端数量:2当前客户端的IP:127.0.0.1我是服务器,客户端说:用户名:tom;密码:456
客户端:
我是客户端,服务端说:欢迎您!
知识点补充:
在的总结中有说过:根据java api,Thread类本身也是实现了Runnable接口,有:
“When an object implementing interface Runnable is used to create a thread, starting the thread causes the object’s run method to be called in that separately executing thread.”
当使用实现接口runnable的对象来创建线程时,启动线程会导致在单独执行的线程中调用对象的run方法。2. start()方法:
根据java api,start()方法是Thread的类方法:
“Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.”
“start()方法会使得该线程开始执行;java虚拟机会去调用该线程的run()方法。”因此,t.start()会导致run()方法被调用,run()方法中的内容称为线程体,它就是这个线程需要执行的工作。
用start()来启动线程,实现了真正意义上的启动线程,此时会出现异步执行的效果,即在线程的创建和启动中所述的随机性。‘ 而如果使用run()来启动线程,就不是异步执行了,而是同步执行,不会达到使用线程的意义。
参考链接: