Java 基于TCP协议的Socket编程和通信 案例2

Java 基于TCP协议的Socket编程和通信 参考学习网址:
https://blog.csdn.net/mengxianglong123/article/details/88559138
参考网址:
https://blog.csdn.net/u011460827/article/details/41654257
https://www.iteye.com/blog/hq82001-2273333
增加循环调用:
http://c.biancheng.net/view/1199.html
重点学习:Java,String与InputStream相互转化
网址1:https://blog.csdn.net/u010002184/article/details/51378870
网址2:https://blog.csdn.net/weixin_39248420/article/details/89949880?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-11.control&dist_request_id=1328680.6636.16161141728921237&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-11.control
网址3:https://blog.csdn.net/macwhirr123/article/details/9236307?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control&dist_request_id=1328680.6636.16161141728921237&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control

1.String to InputStream String str = "String与InputStream相互转换"; InputStreamin_nocode=newByteArrayInputStream(str.getBytes()); InputStreamin_withcode=newByteArrayInputStream(str.getBytes("UTF-8"));

java 转换流InputStreamReader和OutputStreamWriter
网址1: https://blog.csdn.net/sinat_41132860/article/details/84347701
在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序,简称客户端,而在第一次通讯中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。
请求-响应”模式:
1. Socket类:发送TCP消息。
2. ServerSocket类:创建服务器。
套接字是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在通过网络连接的不同机器上。换句话说,套接字起到通信端点的作用。单个套接字是一个端点,而一对套接字则构成一个双向通信信道,使非关联进程可以在本地或通过网络进行数据交换。一旦建立套接字连接,数据即可在相同或不同的系统中双向或单向发送,直到其中一个端点关闭连接。套接字与主机地址和端口地址相关联。主机地址就是客户端或服务器程序所在的主机的IP地址。端口地址是指客户端或服务器程序使用的主机的通信端口。
在客户端和服务器中,分别创建独立的Socket,并通过Socket的属性,将两个Socket进行连接,这样,客户端和服务器通过套接字所建立的连接使用输入输出流进行通信。TCP/IP套接字是最可靠的双向流协议,使用TCP/IP可以发送任意数量的数据。
TCP/IP通信连接的简单过程:
位于A计算机上的TCP/IP软件向B计算机发送包含端口号的消息,B计算机的TCP/IP软件接收该消息,并进行检查,查看是否有它知道的程序正在该端口上接收消息。如果有,他就将该消息交给这个程序。
要使程序有效地运行,就必须有一个客户端和一个服务器。
通过Socket的编程顺序:
1. 创建服务器ServerSocket,在创建时,定义ServerSocket的监听端口(在这个端口接收客户端发来的消息)。
2. ServerSocket调用accept()方法,使之处于阻塞状态。
3. 创建客户端Socket,并设置服务器的IP及端口。
4. 客户端发出连接请求,建立连接。
5. 分别取得服务器和客户端Socket的InputStream和OutputStream。
6. 利用Socket和ServerSocket进行数据传输。
7. 关闭流及Socket。
一、单向通信 1、服务器端
import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; /** * 最简单的服务器端代码 * @author Administrator */ public class BasicSocketServer { public static void main(String[] args) { Socket socket = null; BufferedWriter bw = null; try { // 建立服务器端套接字:指定监听的接口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端建立监听"); // 监听,等待客户端请求,并愿意接收连接 socket = serverSocket.accept(); // 获取socket的输出流,并使用缓冲流进行包装 bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 向客户端发送反馈信息 bw.write("hhhh"); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭流及socket连接 if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

2、客户端
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.Socket; /** * 最简单的Socket客户端 * @author Administrator */ public class BasicSocketClient { public static void main(String[] args) { Socket socket = null; BufferedReader br = null; try { /* * 创建Scoket对象:指定要连接的服务器的IP和端口而不是自己机器的 * 端口。发送端口是随机的。 */ socket = new Socket(InetAddress.getLocalHost(), 8888); //获取scoket的输入流,并使用缓冲流进行包装 br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //接收服务器端发送的信息 System.out.println(br.readLine()); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流及socket连接 if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

二、双向通信 1、服务器端
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args){ Socket socket = null; BufferedReader in = null; BufferedWriter out = null; BufferedReader br = null; try { //创建服务器端套接字:指定监听端口 ServerSocket server = new ServerSocket(8888); //监听客户端的连接 socket = server.accept(); //获取socket的输入输出流接收和发送信息 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); br = new BufferedReader(new InputStreamReader(System.in)); while (true) { //接收客户端发送的信息 String str = in.readLine(); System.out.println("客户端说:" + str); String str2 = ""; //如果客户端发送的是“end”则终止连接 if (str.equals("end")){ break; } //否则,发送反馈信息 str2 = br.readLine(); // 读到\n为止,因此一定要输入换行符! out.write(str2 + "\n"); out.flush(); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 if(in != null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if(out != null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } if(br != null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

2、客户端
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] args) { Socket socket = null; BufferedReader in = null; BufferedWriter out = null; BufferedReader wt = null; try { //创建Socket对象,指定服务器端的IP与端口 socket = new Socket(InetAddress.getLocalHost(), 8888); //获取scoket的输入输出流接收和发送信息 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); wt = new BufferedReader(new InputStreamReader(System.in)); while (true) { //发送信息 String str = wt.readLine(); out.write(str + "\n"); out.flush(); //如果输入的信息为“end”则终止连接 if (str.equals("end")) { break; } //否则,接收并输出服务器端信息 System.out.println("服务器端说:" + in.readLine()); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭资源 if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (wt != null) { try { wt.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

三、聊天室 1、服务器端
package cn.menglangpoem.chat; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * 聊天室服务器 */ public class Server { //准备容器,存储客户端 private static List list = new CopyOnWriteArrayList<>(); //主函数 public static void main(String[] args) throws IOException { int num = 0; //创建服务器 ServerSocket server = null; try { server = new ServerSocket(8888); System.out.println("服务器已启动,端口号---->8888"); } catch (IOException e) { e.printStackTrace(); } while(true) { //接收客户端 Socket client = server.accept(); num++; System.out.println(num+"个服务器已连接"); //存储到容器 Chanel chanel = new Chanel(client); list.add(chanel); //开启线程 new Thread(chanel).start(); } } //信号通道 static class Chanel implements Runnable{ private Socket clinet = null; //客户端 private boolean flag = true; //控制运行 private DataInputStream clientR = null; //读信息 private DataOutputStream clientW = null; //写信息 private String name; //客户端姓名 public Chanel(Socket clinet) { this.clinet = clinet; //初始化 try { this.clientR = new DataInputStream(clinet.getInputStream()); this.clientW = new DataOutputStream(clinet.getOutputStream()); this.name = clientR.readUTF(); this.send("欢迎来到聊天室!"); } catch (IOException e) { //e.printStackTrace(); System.out.println("初始化失败!"); flag = false; } } @Override public void run() { while(flag) { sendOthers(); } } //发送 private void send(String msg) { //判断是否为空 try { //System.out.println("send ---- "+msg); clientW.writeUTF(msg); clientW.flush(); } catch (IOException e) { //e.printStackTrace(); System.out.println("发送失败!"); flag = false; } } //接收 private String receive() { String msg = null; try { msg = clientR.readUTF(); } catch (IOException e) { //e.printStackTrace(); System.out.println("接收失败!"); flag = false; } return msg; } //发送群消息 private void sendOthers() { String msg = receive(); for(Chanel other: list) { if(other == this) continue; else { other.send(this.name+"说"+msg); } } } } }

【Java 基于TCP协议的Socket编程和通信 案例2】2、客户端
package cn.menglangpoem.chat; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.Scanner; /** * 聊天客户端 */ public class Client { public static void main(String[] args) throws IOException { //连接服务器 Socket server = new Socket("localhost",8888); //启动线程 new Thread(new Send(server)).start(); new Thread(new Receive(server)).start(); System.out.println("请输入昵称"); } //接收信息 static class Receive implements Runnable{ private Socket server = null; private boolean flag = true; DataInputStream serverR = null; //构造函数 public Receive(Socket server) { //初始化 this.server = server; try { this.serverR = new DataInputStream(server.getInputStream()); } catch (IOException e) { e.printStackTrace(); flag = false; } } @Override public void run() { while (flag) { System.out.println(receive()); } } private String receive() { String msg = null; try { msg = serverR.readUTF(); } catch (IOException e) { //e.printStackTrace(); System.out.println("接收信息失败!"); flag = false; } return msg; } } //发送信息 static class Send implements Runnable{ private Socket server = null; private DataOutputStream serverW = null; private boolean flag = true; public Send(Socket server) { this.server = server; try { serverW = new DataOutputStream(server.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } } //线程体 @Override public void run() { while (flag) send(); } //发送函数 private void send() { Scanner scanner = new Scanner(System.in); String msg = scanner.next(); try { serverW.writeUTF(msg); serverW.flush(); } catch (IOException e) { e.printStackTrace(); System.out.println("发送信息失败!"); flag = false; } } } }

    推荐阅读