一、网络编程实现客户端与服务端一对一聊天:
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() {
@Override
public 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() {
@Override
public void run() {
// System.out.println("请输入任意内容准备回复客户端:");
sd.Receive();
}
}).start();
sd.sendMssage();
}
}
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() {
@Override
public 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(){
@Override
public 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() {
@Override
public 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 lists = new ArrayList();
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 args
public void sendAllMessageThreadBykeyboard(){
new Thread(new Runnable() {
@Override
public 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 socketlist;
private BufferedReader br;
public ReceiveThread(Socket socket,ArrayList lists) throws IOException{
this.socket = socket;
this.socketlist = lists;
this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Thread t = new Thread(this);
t.start();
}
@Override
public 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 arrayList;
private Socket socket;
public SendMessage(ArrayList lists){
this.arrayList = lists;
this.socket = socket;
new Thread(this).start();
}
@Override
public void run() {
/**
* 键盘写入缓冲流,缓冲流读出来的内容,再写到scoket 控制台:
* 服务端启动!
已成功连接:1
客户端:dawdwdwa
qq
客户端: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