网络编程一对一、群聊(socket、io、线程、匿名内部类)

来源:互联网 发布:淘宝如何快速上架 编辑:程序博客网 时间:2024/05/06 21:42

一、网络编程实现客户端与服务端一对一聊天:

package cn.socket.day24;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;/** *客户端 *理解:从键盘输入程序,通过缓冲流按行读取,同时写进数据处理流(负责发送) */public class ClientDemo {private static final String IP = "192.168.1.8";//ip地址private static final int PORT = 9527;//端口private BufferedReader br;private DataOutputStream dos;private Socket socket;private DataInputStream dis;public void StartClient(){try {socket = new Socket(IP,PORT);//发起请求,打开socket连接/** * 写 */OutputStream os = socket.getOutputStream();//获得输出流、返回此套接字的输出流。dos = new DataOutputStream(os);//转换成数据处理流,负责发送数据/** * 读 */InputStream is = socket.getInputStream();dis = new DataInputStream(is);/** * 获取键盘输入 */InputStreamReader isr = new InputStreamReader(System.in);br = new BufferedReader(isr);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/** * 发送信息:在这里用到br、dos、socket报错,应将对应流(类)定义为全局变量 * 理解:从键盘输入内容按行读到程序,再写进输出流(数据处理流),输出流负责发送 */public void sendMessage() {try {String s = br.readLine();while (!s.equals("*")) {//System.out.println("请输入内容开始传输:");s = br.readLine();// 从键盘读到程序,缓冲流按行读dos.writeUTF(s);// 从缓冲流读到程序,再写进输出流}} catch (IOException e) {e.printStackTrace();}try {if(dos!=null)dos.close();} catch (IOException e) {e.printStackTrace();}}/** * 接收信息: * 理解:服务端输出流到输出信息流,客户端输入流通过信息流读取 *  */public void receiveMessage(){boolean flag = true;while(flag){try {String message = dis.readUTF();if(message != null)//if判断句,当只有一句话时,可以省略大括号System.out.println("服务端:"+message);} catch (IOException e) {e.printStackTrace();}System.out.println("回复服务端:");}try {socket.close();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {ClientDemo cd = new ClientDemo();cd.StartClient();/** * 匿名内部类、线程 */new Thread(new Runnable() {@Overridepublic void run() {cd.receiveMessage();}}).start();;//System.out.println("请输入任意内容准备传输:");cd.sendMessage();}}

package cn.socket.day24;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {private static final int PORT = 9527;private Socket socket;private DataOutputStream dos;private BufferedReader br;//private BufferedReader socketReader;private DataInputStream dis;/** * 建立连接 */public void startServer(){System.out.println("服务器启动:");//DataInputStream dis = null;try {ServerSocket serverSocket = new ServerSocket(PORT);//创建绑定到特定端口的服务器套接字。System.out.println("开始监听!");socket = serverSocket.accept();// 监听|侦听并接受到此套接字的连接。System.out.println("连接成功!");/** * 读 */InputStream is = socket.getInputStream();// 获得输入流、返回此套接字的输入流。//InputStreamReader isr1 = new InputStreamReader(is);//socketReader= new BufferedReader(isr1);dis = new DataInputStream(is);// 数据处理流、接收信息/** * 写 */OutputStream os = socket.getOutputStream();dos = new DataOutputStream(os);/** * 获取键盘输入 */InputStreamReader isr = new InputStreamReader(System.in);br = new BufferedReader(isr);} catch (IOException e) {e.printStackTrace();}}/** * 接收信息: * 客户端从键盘输入内容按行读到程序,再写进输出流(数据处理流),输出流负责发送到信息流。服务端通过输入流在信息流内读取 */public void Receive(){boolean flag = true;//如不定义布尔值,socket只能在循环能关闭while(flag){try {String message = dis.readUTF();if(message != null)System.out.println("客户端:"+message);//System.out.println("请输入任意内容准备回复客户端:");} catch (IOException e) {e.printStackTrace();}}//try {//socket.close();//} catch (IOException e) {//e.printStackTrace();//}}/** * 发送消息 */public void sendMssage(){try {String message = br.readLine();while(!message.equals("#")){//System.out.println("请回复客户端:");message = br.readLine();dos.writeUTF(message);//socket.close();}} catch (IOException e) {e.printStackTrace();}}/**服务器启动:开始监听!连接成功!客户端:你好开始你好呀客户端:谢谢启动服务端开始监听—>阻塞等待客户端启动-->客户端启动连接成功客户端和服务端第一次发消息时,需要任意内容后在键入内容才开始正式 */public static void main(String[] args) {ServerDemo sd = new ServerDemo();sd.startServer();new Thread(new Runnable() {@Overridepublic void run() {//System.out.println("请输入任意内容准备回复客户端:");sd.Receive();}}).start();sd.sendMssage();}}

一、1.2:

package cn.socket.chat.day25;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;public class CilentDemo {private static final String IP = "192.168.1.8";private static final int PORT = 9528;private Socket socket;private PrintWriter socketWriter;private BufferedReader keyboardReader; private BufferedReader socketReader;public void startClient(){try {socket = new Socket(IP,PORT);//发起socket请求,/** * 写 *///OutputStream os = socket.getOutputStream();//返回此套接字的输出流。//socketWriter = new PrintWriter(os);//通过现有的 OutputStream 创建新的 PrintWriter。socketWriter = new PrintWriter(socket.getOutputStream());/** * 读 *///InputStream is = socket.getInputStream();//返回此套接字的输入流。//InputStreamReader isr = new InputStreamReader(is);//socketReader = new BufferedReader(isr);socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));/** * 获取键盘输入 *///InputStreamReader isr1 = new InputStreamReader(System.in);//keyboardReader = new BufferedReader(isr1);keyboardReader = new BufferedReader(new InputStreamReader(System.in));} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/** * 发送消息,在这里需要用到socketWriter和keyboardReader。所以需要将上面对应流定义为全局变量 */public void sendMessage(){System.out.println("输入向服务端发送的聊天内容1:");String message;try {message = keyboardReader.readLine();while(!message.equals("exit")){socketWriter.println(message);socketWriter.flush();//刷新该流的缓冲。message = keyboardReader.readLine();//System.out.println("输入聊天内容:");}} catch (IOException e) {System.out.println("结束聊天2!");//e.printStackTrace();}socketWriter.close();}/** * 接收消息:在这里需要用到socketReader,所以需要将上面对应流定义为全局变量 */public void ReceiveMessage() {boolean isStop = true;while (isStop) {try {String message = socketReader.readLine();if(message != null){System.out.println("服务端:"+message);}} catch (IOException e) {System.out.println("结束聊天!");//e.printStackTrace();}System.out.println("回复服务端:");}try {socket.close();//关闭流} catch (IOException e) {e.printStackTrace();}}/**控制台: *  输入向服务端发送的聊天内容1:你好,我是客户端服务端:好的回复服务端:。服务端:0回复服务端: */public static void main(String[] args) {final CilentDemo cd = new CilentDemo();cd.startClient();/** * 匿名内部类 */new Thread(new Runnable() {@Overridepublic void run() {cd.ReceiveMessage();//在内部类访问(ReceiveMessage();)方法时需要加final。或者CilentDemo cd定义为全局变量}}).start();cd.sendMessage();}}

package cn.socket.chat.day25;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;/** *服务端 *第一步:建立连接 *1.实例化ServerSocket *  2.监听端口有无连接请求 *   *第二步:接收信息实质是从socket输入流中读取数据 *      发送信息实质是向socket输出流写数据 */public class ServerDemo {private static final int PORT = 9528;//端口号private BufferedReader socketReader;private Socket socket;private PrintWriter socketWriter;private BufferedReader keyBoardReader;/** * 建立连接 */public void startSever(){try {ServerSocket serverSocket = new ServerSocket(PORT);//创建绑定到特定端口的服务器套接字。System.out.println("开始监听");socket = serverSocket.accept();//监听|侦听并接受到此套接字的连接。System.out.println("建立连接成功!");socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//接收信息socketWriter = new PrintWriter(socket.getOutputStream());//发送信息keyBoardReader = new BufferedReader(new InputStreamReader(System.in));//从键盘读数据} catch (IOException e) {e.printStackTrace();}}/** * 接收信息: *子线程 */public void receiveMessage(){new Thread(new Runnable(){@Overridepublic void run() {boolean isStop = true;while(isStop){try {String message = socketReader.readLine();if(message != null){System.out.println("客户端:"+message);System.out.println("请回复客户端:");}} catch (IOException e) {isStop = false;e.printStackTrace();}}try {socket.close();} catch (IOException e) {e.printStackTrace();}}}).start();}/** * 发送信息: * 主线程 */public void sendMessage(){try {String message = keyBoardReader.readLine();while(!message.equals("exit")){//System.out.println("请输入向客户端发送的内容:");socketWriter.println(message);socketWriter.flush();//刷新message = keyBoardReader.readLine();}socket.close();} catch (IOException e) {e.printStackTrace();}}/**控制台:当启动服务端,服务端控制台显示:开始监听。当启动客户端,服务端控制台显示:建立连接成功! * 开始监听建立连接成功!客户端:你好,我是客户端请回复客户端:好的客户端:。请回复客户端:0 */public static void main(String[] args){ServerDemo sd = new ServerDemo();sd.startSever();sd.receiveMessage();sd.sendMessage();}}

二、实现多人聊天:

package cn.socket.multiuserchats.day26;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;/** *客户端 *理解:从键盘输入程序,通过缓冲流按行读取,同时写进数据处理流(负责发送) */public class ClientDemo {private static final String IP = "192.168.5.41";//ip地址private static final int PORT = 9527;//端口private BufferedReader br;private DataOutputStream dos;private Socket socket;private DataInputStream dis;private PrintWriter pw;private BufferedReader br1;public void StartClient(){try {socket = new Socket(IP,PORT);//发起请求,打开socket连接/** * 写 */OutputStream os = socket.getOutputStream();//获得输出流、返回此套接字的输出流。pw = new PrintWriter(os);//dos = new DataOutputStream(os);//转换成数据处理流,负责发送数据/** * 读 */InputStream is = socket.getInputStream();br1 = new BufferedReader(new InputStreamReader(is));//dis = new DataInputStream(is);/** * 获取键盘输入 */InputStreamReader isr = new InputStreamReader(System.in);br = new BufferedReader(isr);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/** * 发送信息:在这里用到br、dos、socket报错,应将对应流(类)定义为全局变量 * 理解:从键盘输入内容按行读到程序,再写进输出流(数据处理流),输出流负责发送 */public void sendMessage() {System.out.println("请输入任意内容准备传输:");try {String s = br.readLine();while (!s.equals("*")) {System.out.println("请输入内容开始传输:");s = br.readLine();// 从键盘读到程序,缓冲流按行读//dos.writeUTF(s);// 从数据流读到程序,再写进输出流pw.println(s);//此处用BufferedWriter写不到服务端pw.flush();}} catch (IOException e) {e.printStackTrace();}//try {//if(dos!=null)//dos.close();//} catch (IOException e) {//e.printStackTrace();//}}/** * 接收信息: * 理解:服务端输出流到输出信息流,客户端输入流通过信息流读取 *  */public void receiveMessage(){boolean flag = true;while(flag){try {//String message = dis.readUTF();String message = br1.readLine();if(message != null)//if判断句,当只有一句话时,可以省略大括号System.out.println("服务端:"+message);} catch (IOException e) {e.printStackTrace();}System.out.println("回复服务端:");}try {socket.close();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {final ClientDemo cd = new ClientDemo();cd.StartClient();/** * 匿名内部类、线程 */new Thread(new Runnable() {@Overridepublic void run() {cd.receiveMessage();}}).start();;cd.sendMessage();}}

package cn.socket.multiuserchats.day26;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;public class MulThread {private static final int PORT = 9527;private ArrayList<Socket> lists = new ArrayList<Socket>();private BufferedReader br;public void startServer(){try {System.out.println("服务端启动!");ServerSocket serverSocket = new ServerSocket(PORT);//br = new BufferedReader(new InputStreamReader(System.in));//sendAllMessageThreadBykeyboard();new SendMessage(lists);while(true){Socket socket = serverSocket.accept();//监听lists.add(socket);System.out.println("已成功连接:"+lists.size());new ReceiveThread(socket,lists);}} catch (IOException e) {e.printStackTrace();}}/** * 群发线程:方式一:匿名内部类    方式二:SendMessage线程实现Runablb * @param argspublic void sendAllMessageThreadBykeyboard(){new Thread(new Runnable() {@Overridepublic void run() {try {String message = br.readLine();while(!message.equals("exit")){sendAllMessage(message);message = br.readLine();}} catch (IOException e) {e.printStackTrace();}}}).start();}public void sendAllMessage(String message) throws IOException{if(lists.size() ==0){return;}for(Socket socket : lists){PrintWriter pw = new PrintWriter(socket.getOutputStream());pw.println(message);pw.flush();}}/** * 服务端启动!已成功连接:1客户端:x bnsxnsbxsjx客户端:xhaXBAJajxbx客户端:xaxhjxaxhjXHkHXKxxAXKJaKLxja客户端:sbxSBXsxsbxSB客户端:xnKXNAxaxnKXN客户端:xkNXaknxkx已成功连接:2 * @param args */public static void main(String[] args) {MulThread mt = new MulThread();mt.startServer();}}

package cn.socket.multiuserchats.day26;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.util.ArrayList;public class ReceiveThread implements Runnable{private Socket socket;private ArrayList<Socket> socketlist;private BufferedReader br;public ReceiveThread(Socket socket,ArrayList<Socket> lists) throws IOException{this.socket = socket;this.socketlist = lists;this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));Thread t = new Thread(this);t.start();}@Overridepublic void run() {ReceiveMessage();}/** * 接收客户端发送的信息 * @throws IOException */public void ReceiveMessage(){boolean flag = true;while(flag){try {String message = br.readLine();if(message != null){System.out.println("客户端:"+message);changeAllMessage(message);}} catch (IOException e) {flag = false;}}}/** * 转发接收到的信息到已连接客户端 * @throws IOException  */public void changeAllMessage(String message) throws IOException{for(Socket socket : socketlist){if(this.socket == socket){continue;}PrintWriter pw = new PrintWriter(socket.getOutputStream());pw.println(message);pw.flush();}}}

package cn.socket.multiuserchats.day26;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.util.ArrayList;public class SendMessage implements Runnable{private ArrayList<Socket> arrayList;private Socket socket;public SendMessage(ArrayList<Socket> lists){this.arrayList = lists;this.socket = socket;new Thread(this).start();}@Overridepublic void run() {/** * 键盘写入缓冲流,缓冲流读出来的内容,再写到scoket  控制台: * 服务端启动!已成功连接:1客户端:dawdwdwaqq客户端:ddwadwa */BufferedReader br = new BufferedReader(new InputStreamReader(System.in));try {String message = br.readLine();while(!message.equals("exit")){if(arrayList.size() != 0){for(Socket socket : arrayList){PrintWriter pw = new PrintWriter(socket.getOutputStream());pw.println(message);//写pw.flush();//刷新}}message = br.readLine();}} catch (IOException e) {e.printStackTrace();}}}

小结:

网络编程: 

1. C/S   Client/Server    客户端/服务端模式   --->网络套接字实现

连接过程: 服务端:监听对应端口连接        客户端:根据ip、端口号发起socket请求

类似电话: 被叫方:监听来电                        主叫方:根据电话号码打电话

2.B/S     Brower/Server   浏览器/服务器模式

URL统一资源定位符    作用:表示网络中资源

格式:协议://ip地址/域名/主机名、端口号/路径/文件

http://192.168.5.4:80/webapp/index.html


0 0
原创粉丝点击