Java网络编程学习笔记
1 网络基础
1.1 网络通信
? 1.概念:两台设备之间通过网络实现实现数据传输
? 2.网络通信:将数据通过网络从一台设备传输到另一台设备
? 3.java.net包下提供了一系列的类或接口,供程序员使用,完成网络通信
1.2 网络
? 1.概念:两台或多台设置通过一定物理设备连接起来构成了网络
? 2.根据网络的覆盖范围不同,对网络进行分类:
? 。局域网:覆盖范围小,仅仅覆盖一个教室或一个机房
? 。城域网:覆盖范围较大,可以覆盖一个城市
? 。广域网:覆盖范围最大,可以覆盖全国,甚至全球,万维网是广域网的代表
1.3 IP地址
? 1.概念:用于唯一标识网络中的每台计算机/主机
? 2.查看ip地址:ipconfig
? 3.ip地址的表示形式:点分十进制 xxx.xxx.x.xx 比如:192.168.1.101
? 4.每个十进制数的范围是:0-255
IP表示:对于IPv4 4个字节(32位)表示 192.168.1.101
? 1个字节的范围是0-255
第1个字节 | 第2个字节 | 第3个字节 | 第4个字节 |
---|
1111 1111(8位) | 1111 1111(8位) | 1111 1111(8位) | 1111 1111(8位) | 0-255 2^8 = 256 | 0-255 | 0-255 | 0-255 | 192. | 168. | 1. | 101 |
? 5.ip地址的组成=网络地址+主机地址,比如:192.168.16.69
? 6.IPv6是互联网工程任务组设计的用于替代IPv4的下一代IP协议,
? 其地址数量号称可以为全世界的每一粒沙子编上一个地址
? IPv6 16个字节 128位 表示一个地址
? 7.由于IPv4最大的问题在于网络地址资源有限,严重制约了互联网的应用和发展。
? IPv6的使用,不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍。
IPv4地址分类:
?
1.5 域名
? IP:182.61.200.61
1.域名:www.baidu.com
2.好处:为了方便记忆,解决记ip的困难
3.概念:将ip映射成域名,这里怎么映射上,属于http协议的内容
1.6 端口号
1.概念:用于标识计算机上某个特定的网络程序
2.表示形式:以整数形式,端口范围0-65535 (2个字节:2^16 = 65535)
3.0-1024已经被占用,比如 ssh 22,ftp 21,smtp 25,http 80
4.常见的网络程序端口号:
? tomcat: 8080
? oracle: 1521
? mysql: 3306
? sqlserver:1433
5.HTTP协议的默认端口号是:80
小知识:有的公司,不想让员工上网登录QQ,就会通过防火墙将QQ的端口号禁掉。
1.7 网络通信协议
协议:语言本身就是一种协议,比如:中文 英文 韩语 日语
? 在计算机中,数据的组织形式,就是协议。
协议(tcp/ip):(Transmission Control Protocol/Internet Protocol的简写,中文译名:传输控制协议/因特网互联协议,又叫网络通讯协议。
? 这个协议是Internet最基本的协议,Internet国际互联网络的基础,
? 简单地说,就是由传输层的TCP协议和网络层的IP协议组成的。
? 网络通讯协议模型:
现在用的协议:并没有用理论型的OSI模型,ISO模型分得太细了,现实的网络中,用的是TCP/IP协议。
1.8 TCP协议
TCP/IP协议: 传输控制协议,是一种面向连接的保证可靠传输的协议。
? 通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,
? 以便在TCP协议的基础上进行通信,当一个socket等待建立连接时,另一个socket可以要求进行连接,
? 一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收数据。
? TCP是基于连接的协议,它能够提供两台计算机之间的可靠的数据流,HTTP、FTP、Telnet等应用都需要这种可靠的通信通道。
? 1.使用TCP协议前,须先建立TCP连接,形成传输数据通道
? 2.传输前,采用“三次握手”方式,是可靠的
? 3.TCP协议进行通信的两个应用进程:客户端,服务端
? 4.在连接中可进行大数据量的传输
? 5.传输完毕,需释放已建立的连接,效率低
1.9 UDP协议
UDP协议: 用户数据协议,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,
? 它在网络上以任何可能的路径传往目的地,因此能否到达目的地,
? 到达目的地的时间以及内容的正确性都是不被保证的。
? UDP是从一台计算机向另一台计算机发送称为数据报的独立数据报的协议,该协议并不保证数据报是否能正确地到达目的地。
? 它是一个非面向连接的协议。
? 通常用于传输音频或者视频,视频会议,抖音直播,数据量大的情况,这种都用的UDP协议。
?
? 1.将数据、源、目的封装成数据包,不需要建立连接
? 2.每个数据报的大小限制在64K内,不适合传输大量数据
? 3.因无需连接,故是不可靠的
? 4.发送数据结束时无需释放资源(因为不是面向连接的),速度快
? 5.举例:厕所通知, 发短信
2 IntetAddress IP地址
2.1 getLocalHost()
getLocalHost():获取本机InetAddress对象 获取本机的IP地址对象
InetAddress localHost = InetAddress.getLocalHost();
2.2 getByName()
getByName():根据指定主机名/域名获取 InetAddress对象
InetAddress localHost2 = InetAddress.getByName("tangguanlin2006");
InetAddress localHost3 = InetAddress.getByName("www.baidu.com");
2.3 getHostAddress()
localHost3.getHostAddress():获取InetAddress对象的IP地址
String hostAddress = localHost3.getHostAddress();
2.4 getHostName()
localHost3.getHostName():获取InetAddress对象的主机名/域名
String hostName = localHost3.getHostName();
代码:
package com.tangguanlin.javanet;
import java.net.InetAddress;
public class InetAddressTest {
public static void main(String[] args) throws Exception{
InetAddress localHost = InetAddress.getLocalHost();
System.out.println("getLocalHost():"+localHost);
InetAddress localHost2 = InetAddress.getByName("tangguanlin2006");
System.out.println("getByName():"+localHost2);
InetAddress localHost3 = InetAddress.getByName("www.baidu.com");
System.out.println("localHost3:"+localHost3);
String hostAddress = localHost3.getHostAddress();
System.out.println("getHostAddress():"+hostAddress);
String hostName = localHost3.getHostName();
System.out.println("getHostName():"+hostName);
}
}
运行结果:
getLocalHost():tangguanlin2006/192.168.1.101
getByName():tangguanlin2006/192.168.1.101
localHost3:www.baidu.com/182.61.200.7
getHostAddress():182.61.200.7
getHostName():www.baidu.com
3 Socket
Socket:
? socket的出现,使程序员可以很方便地访问TCP/IP协议,从而开发各种网络应用的程序。
? socket是连接运行在网络上的两个程序间的双向通讯的端点。
? 。服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户的连接请求。
? 。客户程序根据服务器程序所在的主机名和端口号发出连接请求。
? 。如果一切正常,服务器接收连接请求。并获得一个新的绑定到不同端口地址的套接字。
? 。客户和服务器通过读、写套接字进行通讯。
? 1.套接字(Socket)开发网络应用程序被广泛采用,以至于称为事实上的标准,
? 2.通信的两端都要有Socket,是两台机器间通信的端点
? 3.网络通信其实就是Socket间的通信
? 4.Socket运行程序把网络连接当成一个流,数据在两个Socket建通过IO传输
? 5.一般主动发起通信的应用程序属于客户端,等待通信请求的为服务端
? 6.TCP编程和UDP编程,都是借助Socket实现的
? TCP协议类似于 打电话
? UDP协议类似于 写信 发邮件
? 7.JDK对TCP协议和UDP协议都提供了内置的支持。
示意图:
总结:相当于 JDK用Socket屏蔽底层的TCP/IP协议通信实现的细节,我们开发时,只要操作Socket就可以了。
? JDK会完成Socket到TCP/IP协议细节的转换。
4 TCP编程
4.1 基本介绍
? 1.基于客户端–服务端的网络通信
? 2.底层使用的是TCP/IP协议
? 3.应用场景举例:客户端发送数据,服务端接收并显示到控制台
? 4.基于Socket的TCP编程
?
4.2 应用案例1(使用字节流)
? 1.编写服务器端,和一个客户端
? 2.服务器端在9999端口监听
? 3.客户端连接到服务器端,发送“hello,server”,然后退出
? 4.服务器端接收到客户端发送的信息,输出,并退出
示意图:
服务端TCPServer1.java
package com.tangguanlin.javanet;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer1 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端 在9999端监听,等待连接....");
Socket socket = serverSocket.accept();
System.out.println("服务端 socket:"+socket.getClass());
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while((readLen=inputStream.read())!=-1){
System.out.println(new String(buf,0,readLen));
}
inputStream.close();
socket.close();
serverSocket.close();
}
}
运行结果:
服务端 在9999端监听,等待连接....
服务端 socket:class java.net.Socket
hello server
客户端TCPClient1.java
package com.tangguanlin.javanet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClient1 {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端 socket返回"+socket.getClass());
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello server".getBytes());
outputStream.close();
socket.close();
System.out.println("客户端已退出");
}
}
运行结果:
客户端 socket返回class java.net.Socket
客户端已退出
4.3 应用案例2(使用字节流)
? 1.编写一个服务器端,和一个客户端
? 2.服务器端在9999端口监听
? 3.客户端连接到服务器端,发送“hello,server”,并接收服务器端回发的“hello,client”,再退出
? 4.服务器端接收到客户端发送的信息,输出,并发送“hello,client”,再退出
示意图:
代码:
服务端TCPServer2.java
package com.tangguanlin.javanet;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer2 {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端 在9999端监听,等待连接....");
Socket socket = serverSocket.accept();
System.out.println("服务端 socket:"+socket.getClass());
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while((readLen=inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,readLen));
}
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello client".getBytes());
socket.shutdownOutput();
inputStream.close();
outputStream.close();
socket.close();
serverSocket.close();
}
}
运行结果:
服务端 在9999端监听,等待连接....
服务端 socket:class java.net.Socket
hello server
客户端TCPClient2.java
package com.tangguanlin.javanet;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClient2 {
public static void main(String[] args) throws Exception{
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端 socket返回"+socket.getClass());
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello server".getBytes());
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while((readLen=inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,readLen));
}
outputStream.close();
inputStream.close();
socket.close();
System.out.println("客户端已退出");
}
}
运行结果:
客户端 socket返回class java.net.Socket
hello client
客户端已退出
4.4 应用案例3(使用字符流)
? 1.编写一个服务器端,和一个客户端
? 2.服务器端在9999端口监听
? 3.客户端连接到服务器端,发送“hello,server”,并接收服务器端回发的“hello,client”,再退出
? 4.服务器端接收到客户端发送的信息,输出,并发送“hello,client”,再退出
示意图:
代码:
服务器端TCPServer3.java
package com.tangguanlin.javanet;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer3 {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端 在9999端监听,等待连接....");
Socket socket = serverSocket.accept();
System.out.println("服务端 socket:"+socket.getClass());
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String str = bufferedReader.readLine();
System.out.println("服务端 字符流"+str);
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello client 字符流");
bufferedWriter.newLine();
bufferedWriter.flush();
bufferedReader.close();
bufferedWriter.close();
socket.close();
serverSocket.close();
}
}
运行结果:
服务端 在9999端监听,等待连接....
服务端 socket:class java.net.Socket
服务端 字符流hello server
客户端TCPClient3.java
package com.tangguanlin.javanet;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClient3 {
public static void main(String[] args) throws Exception{
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端 socket返回"+socket.getClass());
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello server");
bufferedWriter.newLine();
bufferedWriter.flush();
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String str = bufferedReader.readLine();
System.out.println("客户端 字符流"+str);
bufferedWriter.close();
bufferedReader.close();
socket.close();
System.out.println("客户端已退出");
}
}
运行结果:
客户端 socket返回class java.net.Socket
客户端 字符流hello client 字符流
客户端已退出
4.5 应用案例4(上传文件)
? 1.编写一个服务端,和一个客户端
? 2.服务器端在8888端口监听
? 3.客户端连接到服务端,发送 一张图片 e:\qie.png
? 4.服务器端接收到客户端发送的图片,保存到src下,发送“收到图片”再退出
? 5.客户端接收到服务端发送的“收到图片”,再退出
? 6.该程序要求使用StreamUtils.java
说明:使用BufferedInputStream和BufferedOutputStream字节流
示意图:
代码:
服务端TCPServer4.java
package com.tangguanlin.javanet;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer4 {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端 在9999端监听,等待连接....");
Socket socket = serverSocket.accept();
System.out.println("服务端 socket:"+socket.getClass());
InputStream inputStream = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
byte[] bytes1 = byteArrayOutputStream.toByteArray();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\112.jpg"));
bos.write(bytes1);
bos.flush();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write("收到图片");
bufferedWriter.newLine();
bufferedWriter.flush();
bufferedWriter.close();
bos.close();
bis.close();
socket.close();
serverSocket.close();
}
}
运行结果:
服务端 在9999端监听,等待连接....
服务端 socket:class java.net.Socket
客户端TCPClient4.java
package com.tangguanlin.javanet;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClient4 {
public static void main(String[] args) throws Exception{
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
System.out.println("客户端 socket返回"+socket.getClass());
FileInputStream fileInputStream = new FileInputStream("D:\\11.jpg");
BufferedInputStream bis = new BufferedInputStream(fileInputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
byte[] bytes1 = byteArrayOutputStream.toByteArray();
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(bytes1);
bos.flush();
socket.shutdownOutput();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = bufferedReader.readLine();
System.out.println("客户端 "+str);
bufferedReader.close();
bos.close();
bis.close();
byteArrayOutputStream.close();
socket.close();
System.out.println("客户端已退出");
}
}
运行结果:
客户端 socket
返回class java.net.Socket
客户端 收到图片
客户端已退出
4.6 应用案例5(下载文件)
? 1.编写客户端程序和服务端程序
? 2.客户端可以输入一个音乐文件名,比如:高山流水,
? 服务端收到音乐名后,可以给客户端返回这个音乐名称,
? 如果服务器端没有这个文件,就返回一个默认的音乐即可。
? 3.客户端收到文件后,保存到本地E:\
示意图:
代码:
服务端TCPServer6.java
package com.tangguanlin.javanet;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer6 {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端 在9999端监听,等待连接....");
Socket socket = serverSocket.accept();
System.out.println("服务端 socket:"+socket.getClass());
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String str = reader.readLine();
System.out.println(str);
FileInputStream fileInputStream = new FileInputStream("F:\\02mp3\\002.Beyond-情人.mp3");
BufferedInputStream bis = new BufferedInputStream(fileInputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
byte[] bytes1 = byteArrayOutputStream.toByteArray();
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(bytes1);
bos.flush();
socket.shutdownOutput();
bos.close();
bis.close();
socket.close();
serverSocket.close();
}
}
运行结果:
服务端 在9999端监听,等待连接....
服务端 socket:class java.net.Socket
高山流水
客户端TCPClient6.java
package com.tangguanlin.javanet;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClient6 {
public static void main(String[] args) throws Exception{
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
System.out.println("客户端 socket返回"+socket.getClass());
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write("高山流水".getBytes());
bos.flush();
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
byte[] bytes1 = byteArrayOutputStream.toByteArray();
bos = new BufferedOutputStream(new FileOutputStream("F:\\002.Beyond-情人.mp3"));
bos.write(bytes1);
bos.flush();
bos.close();
bis.close();
byteArrayOutputStream.close();
socket.close();
System.out.println("客户端已退出");
}
}
运行结果:
客户端 socket返回class java.net.Socket
客户端已退出
4.7 netstat指令
1.netstat 可以查看当前主机网络情况
2.netstat -an 可以查看当前主机网络情况,包括端口监听情况和网络连接情况
3.netstat -an|more 可以分页显示
4.要求在dos控制台执行
4.8 TCP连接秘密
? 1.当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,
? 这个端口是TCP/IP来分配的,是不确定的,是随机的。
? 2.示意图:
?
? 3.程序验证+netstat
5 UDP编程
5.1 基本介绍
? Datagram数据报是网上传输的独立数据报,数据报是否能正确地到达目的地,到达的时间,顺序,内容的正确性均没有保障。
? Java中使用Datagram与DatagramPacket来实现UDP协议
? 1.类DatagramSocke[]t和DatagramPacket[数据包/数据报]实现了基于UDP协议网络程序。
? 2.UDP数据报通过数据报套接字DatagramSocket发送和接收,
? 系统不保证UDP数据报一定能够安全到达目的地,也不能确定什么时候可以到达。
? 3.DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
? 4.UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。
5.2 基本流程
1.核心的两个类/对象DatagramSocket与DatagramPacket
2.建立发送端,接收端(没有服务端和客户端概念)
3.发送数据前,建立数据包/报,DatagramPacket对象
4.调用DatagramSocket的发送、接收方法
5.关闭DatagramSocket
示意图:
5.3 应用案例1
? 1.编写一个接收端,和一个发送端
? 2.接收端在9999端口等待接收数据(receive)
? 3.发送端向接收端发送数据“hello,明天吃火锅”
? 4.接收端接收到发送端发送的数据,回复“好的,明天见”,再退出
? 5.发送端接收回复的数据,再退出
分析思路:
代码:
发送端UDPSender1.java
package com.tangguanlin.javanet;
import java.io.IOException;
import java.net.*;
public class UDPSender1 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(9998);
byte[] bytes = "hello,明天吃火锅".getBytes();
InetAddress inetAddress = InetAddress.getByName("192.168.1.101");
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, inetAddress, 9999);
socket.send(packet);
System.out.println("信息已发出");
byte[] buf = new byte[64*1024];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
int length = packet.getLength();
bytes = packet.getData();
String str = new String(bytes,0,length);
System.out.println("发送端收到:"+str);
socket.close();
System.out.println("发送端退出");
}
}
运行结果:
信息已发出
发送端收到:好的,明天见
发送端退出
接收端UDPReceiver1.java
package com.tangguanlin.javanet;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPReceiver1 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(9999);
byte[] buf = new byte[64*1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
System.out.println("接收端等待接收数据");
socket.receive(packet);
int length = packet.getLength();
byte[] bytes = packet.getData();
String str = new String(bytes,0,length);
System.out.println("接收端收到:"+str);
bytes = "好的,明天见".getBytes();
packet = new DatagramPacket(bytes, 0, bytes.length, packet.getAddress(), packet.getPort());
socket.send(packet);
socket.close();
}
}
运行结果:
接收端等待接收数据
接收端收到:hello,明天吃火锅
5.4 应用案例2
? 编程题:
? 1.编写一个接收端,和一个发送端,使用UDP协议完成
? 2.接收端在8888端口等待接收数据
? 3.发送端想接收端发送数据“四大名著是哪些”
? 4.接收端接收到发送端发送的问题后,返回“四大名著是《红楼梦》《三国演义》《西游记》《水浒传》”,
? 否则返回what?
? 5.接收端和发送端程序退出
代码:
发送端UDPSender2.java
package com.tangguanlin.javanet;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPSender2 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(8887);
byte[] bytes = "四大名著是哪些".getBytes();
InetAddress inetAddress = InetAddress.getByName("192.168.1.101");
DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length, inetAddress,8888);
socket.send(packet);
bytes = new byte[64*1024];
packet = new DatagramPacket(bytes, bytes.length);
socket.receive(packet);
int len = packet.getLength();
byte[] data = packet.getData();
String str = new String(data, 0, len);
System.out.println(str);
socket.close();
}
}
运行结果:
四大名著是《红楼梦》《三国演义》《西游记》《水浒传》
接收端UDPReceiver2.java
package com.tangguanlin.javanet;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPReceiver2 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(8888);
byte[] bytes = new byte[64*1024];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
socket.receive(packet);
int len = packet.getLength();
byte[] data = packet.getData();
String str = new String(data, 0, len);
System.out.println(str);
String replayMessge = "";
if("四大名著是哪些".equals(str)){
replayMessge ="四大名著是《红楼梦》《三国演义》《西游记》《水浒传》";
}else{
replayMessge="what";
}
bytes = replayMessge.getBytes();
packet = new DatagramPacket(bytes,0, bytes.length,packet.getAddress(),packet.getPort());
socket.send(packet);
socket.close();
}
}
运行结果:
四大名著是哪些
6 多用户通信系统
6.1 为什么选择这个项目
? 1.有趣
? 2.涉及到java各个方面的技术
? -项目框架设计
? -java面向对象编程
? -网络编程
? -多线程
? -IO流
? -MySQL/使用集合充当内存数据库
? 3.巩固旧知识,学习新知识
6.2 项目开发流程
? 需求分析—>设计阶段—>实现阶段---->测试阶段---->实施阶段—>维护阶段
? 500万项目 (30%) (20%) (20%) (20%) (5%) (5%)
在国内,真正花时间最多的节点,还是实现阶段,很多都是一边开发,一边确认需求,一边修改设计,一边补充文档。
需求分析:
? 1.需求分析师:懂技术+懂行业(业务知识:税务,金融)
? 2.出一个需求分析说明文档:该项目功能,客户具体要求
设计阶段:
? 1.架构师/项目经理
? 2.设计工作(UML类图,流程图,模块设计,数据库设计,架构选型:SSH,Spring Boot)
? 3.画原型图(Axure RP)
? 4.组建团队
实现阶段:
? 1.程序员
? 2.完成架构师的模块功能
? 3.测试自己的模块
测试阶段:
? 1.测试人员
? 2.编写测试用例
? 3.黑盒测试
实施阶段:
? 1.实施人员
? 2.项目正确的部署到客户的平台,并保证运行正常
? 3.环境配置部署能力/网络拓扑结构
? 4.经常出差,经常不着家,对家庭不好
? 5.对自身发展不好
? 6.不建议去从事实施人员
维护阶段:
? 1.运维人员
? 2.现场运维
? 3.现场开发:发现bug/项目升级,增加部分功能
6.3 多用户通信需求
? QQ聊天系统
? 1.用户登录
? 2.拉取在线用户列表
? 3.无异常退出(客户端,服务器端)
? 4.私聊
? 5.群聊
? 6.发文件
? 7.服务器推送新闻
6.4 界面设计和思路分析
### 6.4.1 用户登录
1.功能说明
? 因为还没有学习数据库,我们人为规定 用户名/id = 100,密码:123456就可以的登录,其他用户不能登录
? 后面使用HashMap模拟数据库,可以多个用户登录
? 2.思路分析+程序框架图
6.4.2 拉取在线用户列表
6.4.3 无异常退出
思路分析:
6.4.4 私聊
思路分析:
6.4.5 群聊
6.4.6 发文件
思路分析:
6.4.7 服务器推送新闻
思路分析:
6.4.8 离线留言和发文件
? (1).实现离线留言,如果某个用户没有在线,当登录后,可以接收离线的消息
? (2).实现离线发文件,如果某个用户没有在线,当登录后,可以接收离线的文件
思路分析:
6.5 代码实现
6.5.1 客户端QQClient工程
1.User.java
package com.tangguanlin.common;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String userId;
private String password;
public User() {
}
public User(String userId, String password) {
this.userId = userId;
this.password = password;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.Message.java
package com.tangguanlin.common;
import java.io.Serializable;
public class Message implements Serializable {
private static final long serialVersionUID = 1L;
private String sender;
private String receiver;
private String content;
private String mesType;
private String sendTime;
private byte[] fileBytes;
private int fileLen;
private String src ;
private String desc;
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSendTime() {
return sendTime;
}
public void setSendTime(String sendTime) {
this.sendTime = sendTime;
}
public String getMesType() {
return mesType;
}
public void setMesType(String mesType) {
this.mesType = mesType;
}
public byte[] getFileBytes() {
return fileBytes;
}
public void setFileBytes(byte[] fileBytes) {
this.fileBytes = fileBytes;
}
public int getFileLen() {
return fileLen;
}
public void setFileLen(int fileLen) {
this.fileLen = fileLen;
}
}
3.MessageType.java
package com.tangguanlin.common;
public interface MessageType {
String MESSAGE_LOGIN_SUCCESSED = "1";
String MESSAGE_LOGIN_FAIL = "2";
String MESSAGE_COMM_MES = "3";
String MESSAGE_GET_ONLINE_FRIEND = "4" ;
String MESSAGE_RET_ONLINE_FRIEND = "5" ;
String MESSAGE_CLIENT_EXIT = "6";
String MESSAGE_MANY_MES = "7";
String MESSAGE_FILE_MES = "8";
String MESSAGE_NEWS_MES = "9";
}
4.ManageClientConnectServerThread.java
package com.tangguanlin.service;
import java.util.HashMap;
public class ManageClientConnectServerThread {
private static HashMap<String,ClientConnectServerThread> hashmap = new HashMap<String,ClientConnectServerThread>();
public static void addClientConnectServerThread(String userId,ClientConnectServerThread clientConnectServerThread){
hashmap.put(userId,clientConnectServerThread);
}
public static ClientConnectServerThread getClientConnectServerThread(String userId){
return hashmap.get(userId);
}
}
5.QQView.java
package com.tangguanlin.view;
import com.tangguanlin.service.MessageChatService;
import com.tangguanlin.service.UserClientService;
import java.security.Key;
import java.util.Scanner;
public class QQView {
private boolean loop = true;
private String key = "";
private UserClientService userClientService = new UserClientService();
private MessageChatService messageChatService = new MessageChatService();
public static void main(String[] args) throws Exception {
new QQView().mainView();
System.out.println("客户端退出系统");
}
private void mainView() throws Exception {
while(loop){
System.out.println("==========欢迎登录网络通信系统========");
System.out.println(" 1 登录系统");
System.out.println(" 9 退出系统");
System.out.println("请输入你的选择:");
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
key = next;
switch (key){
case "1":
System.out.println("请输入用户号:");
String userId = scanner.next();
System.out.println("请输入密 码:");
String psw = scanner.next();
if(userClientService.checkUser(userId,psw)){
System.out.println("=========欢迎(用户"+userId+"登录成功)===============");
while (loop){
System.out.println("=========网络通讯系统二级菜单(用户 "+userId+")==================");
System.out.println(" 1 显示在线用户列表 ");
System.out.println(" 2 群发消息 ");
System.out.println(" 3 私聊消息 ");
System.out.println(" 4 发送文件 ");
System.out.println(" 9 退出系统 ");
System.out.println("请输入你的选择:");
String key = scanner.next();
switch (key){
case "1":
userClientService.onlineFriendList();
break;
case "2":
System.out.println("请输入想说的话:");
String content = scanner.next();
messageChatService.sendMessageToMany(content,userId);
break;
case "3":
System.out.println("请输入想聊天的用户号(在线):");
String receiverId = scanner.next();
System.out.println("请输入想说的话:");
String content1 = scanner.next();
messageChatService.sendMessageToOne(content1,userId,receiverId);
break;
case "4":
System.out.println("请输入要发送的用户号(在线):");
String receiverId2 = scanner.next();
String filepath = "H:\\117Java IO\\from\\koala.jpg";
messageChatService.sendFileToOne(filepath,userId,receiverId2);
break;
case "9":
loop = false;
userClientService.sendExitMessage();
break;
}
}
}else{
System.out.println("=====登录失败========");
break;
}
break;
case "9":
loop = false;
userClientService.sendExitMessage();
break;
}
}
}
}
6.UserClientService.java
package com.tangguanlin.service;
import com.tangguanlin.common.Message;
import com.tangguanlin.common.MessageType;
import com.tangguanlin.common.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class UserClientService {
private User user = new User();
private Socket socket;
public boolean checkUser(String userId,String pwd) throws Exception {
boolean b = false;
user.setUserId(userId);
user.setPassword(pwd);
socket = new Socket(InetAddress.getLocalHost(), 9999);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(user);
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
Message msg = (Message)objectInputStream.readObject();
if(msg.getMesType().equals(MessageType.MESSAGE_LOGIN_SUCCESSED)){
ClientConnectServerThread clientConnectServerThread = new ClientConnectServerThread(socket);
clientConnectServerThread.start();
ManageClientConnectServerThread.addClientConnectServerThread(userId,clientConnectServerThread);
b = true;
}else{
socket.close();
}
return b;
}
public void onlineFriendList() throws IOException {
Message message = new Message();
message.setSender(user.getUserId());
message.setMesType(MessageType.MESSAGE_GET_ONLINE_FRIEND);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
ManageClientConnectServerThread.getClientConnectServerThread(user.getUserId()).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
}
public void sendExitMessage() throws IOException {
Message message = new Message();
message.setMesType(MessageType.MESSAGE_CLIENT_EXIT);
message.setSender(user.getUserId());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
ManageClientConnectServerThread.getClientConnectServerThread(user.getUserId()).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
System.out.println(user.getUserId()+"退出系统");
System.exit(0);
}
}
7.MessageChatService.java
package com.tangguanlin.service;
import com.tangguanlin.common.Message;
import com.tangguanlin.common.MessageType;
import java.io.*;
import java.util.Date;
public class MessageChatService {
public void sendMessageToOne(String content,String senderId,String receiverId) throws IOException {
Message message = new Message();
message.setSender(senderId);
message.setReceiver(receiverId);
message.setMesType(MessageType.MESSAGE_COMM_MES);
message.setContent(content);
message.setSendTime(new Date().toString());
System.out.println(senderId+"对"+receiverId+"说:"+content);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
}
public void sendMessageToMany(String content,String senderId) throws IOException {
Message message = new Message();
message.setSender(senderId);
message.setMesType(MessageType.MESSAGE_MANY_MES);
message.setContent(content);
message.setSendTime(new Date().toString());
System.out.println(senderId+"对大家说:"+content);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
}
public void sendFileToOne(String filepath,String senderId,String receiverId) throws IOException {
FileInputStream fileInputStream = new FileInputStream(filepath);
byte[] buff =new byte[(int)new File(filepath).length()];
fileInputStream.read(buff);
fileInputStream.close();
Message message = new Message();
message.setSender(senderId);
message.setReceiver(receiverId);
message.setMesType(MessageType.MESSAGE_FILE_MES);
message.setFileBytes(buff);
message.setSendTime(new Date().toString());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
}
}
8.ClientConnectServerThread.java
package com.tangguanlin.service;
import com.tangguanlin.common.Message;
import com.tangguanlin.common.MessageType;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
public class ClientConnectServerThread extends Thread{
private Socket socket;
public ClientConnectServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
while(true){
System.out.println("客户端线程,等待从读取从服务器端发送的消息");
try {
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
Message message = (Message)objectInputStream.readObject();
if(message.getMesType().equals(MessageType.MESSAGE_RET_ONLINE_FRIEND)){
String[] onlineUsers = message.getContent().split(",");
System.out.println("======当前在线用户列表========");
for(int i=0;i<onlineUsers.length;i++){
System.out.println("用户:"+onlineUsers[i]);
}
}else if(message.getMesType().equals(MessageType.MESSAGE_COMM_MES)){
System.out.println(message.getSender()+"对"+message.getReceiver()+"说:"+message.getContent());
}else if(message.getMesType().equals(MessageType.MESSAGE_MANY_MES)){
System.out.println(message.getSender()+"对大家说:"+message.getContent());
}else if(message.getMesType().equals(MessageType.MESSAGE_FILE_MES)){
byte[] fileBytes = message.getFileBytes();
FileOutputStream fileOutputStream = new FileOutputStream("H:\\117Java IO\\to\\koala.jpg");
fileOutputStream.write(fileBytes);
fileOutputStream.close();
}else if(message.getMesType().equals(MessageType.MESSAGE_NEWS_MES)){
System.out.println("系统推送的消息:"+message.getContent());
}else{
System.out.println("是其他类型的message,暂时不处理....");
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
6.5.2 服务端QQServer工程
1.User.java
package com.tangguanlin.common;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String userId;
private String password;
public User() {
}
public User(String userId, String password) {
this.userId = userId;
this.password = password;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.Message.java
package com.tangguanlin.common;
import java.io.Serializable;
public class Message implements Serializable {
private static final long serialVersionUID = 1L;
private String sender;
private String receiver;
private String content;
private String mesType;
private String sendTime;
private byte[] fileBytes;
private int fileLen;
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSendTime() {
return sendTime;
}
public void setSendTime(String sendTime) {
this.sendTime = sendTime;
}
public String getMesType() {
return mesType;
}
public void setMesType(String mesType) {
this.mesType = mesType;
}
public byte[] getFileBytes() {
return fileBytes;
}
public void setFileBytes(byte[] fileBytes) {
this.fileBytes = fileBytes;
}
public int getFileLen() {
return fileLen;
}
public void setFileLen(int fileLen) {
this.fileLen = fileLen;
}
}
3.MessageType.java
package com.tangguanlin.common;
public interface MessageType {
String MESSAGE_LOGIN_SUCCESSED = "1";
String MESSAGE_LOGIN_FAIL = "2";
String MESSAGE_COMM_MES = "3";
String MESSAGE_GET_ONLINE_FRIEND = "4" ;
String MESSAGE_RET_ONLINE_FRIEND = "5" ;
String MESSAGE_CLIENT_EXIT = "6";
String MESSAGE_MANY_MES = "7";
String MESSAGE_FILE_MES = "8";
String MESSAGE_NEWS_MES = "9";
}
4.ManageServerConnectClientThread.java
package com.tangguanlin.service;
import java.util.HashMap;
import java.util.Set;
public class ManageServerConnectClientThread {
private static HashMap<String,ServerConnectClientThread> hashmap = new HashMap<String,ServerConnectClientThread>();
public static HashMap<String,ServerConnectClientThread> getHashmap(){
return hashmap;
}
public static void addServerConnectClientThread(String userId,ServerConnectClientThread serverConnectClientThread){
hashmap.put(userId,serverConnectClientThread);
}
public static void removeServerConnectClientThread(String userId){
hashmap.remove(userId);
}
public static ServerConnectClientThread getServerConnectClientThread(String userId){
return hashmap.get(userId);
}
public static String getOnlineUser(){
Set<String> onlineUsers = hashmap.keySet();
StringBuffer sb = new StringBuffer();
for(String key:onlineUsers){
sb.append(key).append(",");
}
String sb_temp = sb.toString();
return sb_temp.substring(0,sb_temp.length()-1);
}
}
5.QQFrame.java
package com.tangguanlin.frame;
import com.tangguanlin.service.QQServer;
public class QQFrame {
public static void main(String[] args) throws Exception {
new QQServer();
}
}
6.QQServer.java
package com.tangguanlin.service;
import com.tangguanlin.common.Message;
import com.tangguanlin.common.MessageType;
import com.tangguanlin.common.User;
import javax.sound.midi.Soundbank;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
public class QQServer {
private ServerSocket serverSocket = null;
private static HashMap<String,User> validUsers = new HashMap<>();
static {
validUsers.put("100",new User("100","123456"));
validUsers.put("200",new User("200","123456"));
validUsers.put("300",new User("300","123456"));
validUsers.put("至尊宝",new User("至尊宝","123456"));
validUsers.put("紫霞仙子",new User("紫霞仙子","123456"));
validUsers.put("菩提老祖",new User("菩提老祖","123456"));
}
public boolean checkUser(String userId,String password){
User user = validUsers.get(userId);
if(user==null){
return false;
}
if(!password.equals(user.getPassword())){
return false;
}
return true;
}
public QQServer() throws Exception {
System.out.println("服务器端在9999端口监听...");
ServerPushNewsThread serverPushNewsThread = new ServerPushNewsThread();
serverPushNewsThread.start();
serverSocket = new ServerSocket(9999);
while(true){
Socket socket = serverSocket.accept();
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
User user = (User)objectInputStream.readObject();
Message message = new Message();
if(checkUser(user.getUserId(),user.getPassword())){
message.setMesType(MessageType.MESSAGE_LOGIN_SUCCESSED);
objectOutputStream.writeObject(message);
ServerConnectClientThread serverConnectClientThread = new ServerConnectClientThread(socket, user.getUserId());
serverConnectClientThread.start();
ManageServerConnectClientThread.addServerConnectClientThread(user.getUserId(),serverConnectClientThread);
}else{
System.out.println("用户id="+user.getUserId()+"验证失败");
message.setMesType(MessageType.MESSAGE_LOGIN_SUCCESSED);
objectOutputStream.writeObject(message);
socket.close();
}
}
}
}
7.ServerConnectClientThread.java
package com.tangguanlin.service;
import com.tangguanlin.common.Message;
import com.tangguanlin.common.MessageType;
import javax.sound.midi.Soundbank;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Set;
public class ServerConnectClientThread extends Thread{
private Socket socket;
private String userId;
public ServerConnectClientThread(Socket socket,String userId){
this.socket = socket;
this.userId = userId;
}
@Override
public void run() {
while(true){
System.out.println("服务端和客户端保持通信"+userId+",读取数据...");
try {
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
Message message = (Message)objectInputStream.readObject();
if(message.getMesType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)){
System.out.println(message.getSender()+"要在线用户列表");
String onlineUser = ManageServerConnectClientThread.getOnlineUser();
Message message1 = new Message();
message1.setMesType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
message1.setContent(onlineUser);
message1.setReceiver(message.getSender());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(message1);
}else if(message.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)){
System.out.println(userId+"退出系统");
ManageServerConnectClientThread.removeServerConnectClientThread(userId);
socket.close();
break;
}else if(message.getMesType().equals(MessageType.MESSAGE_COMM_MES)){
ObjectOutputStream objectOutputStream = new ObjectOutputStream( ManageServerConnectClientThread.getServerConnectClientThread(message.getReceiver()).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
}else if(message.getMesType().equals(MessageType.MESSAGE_MANY_MES)){
HashMap<String, ServerConnectClientThread> hashmap = ManageServerConnectClientThread.getHashmap();
Set<String> keySet = hashmap.keySet();
for(String userId:keySet){
if(!userId.equals(message.getSender())){
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
ManageServerConnectClientThread.getServerConnectClientThread(userId).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
}
}
}else if(message.getMesType().equals(MessageType.MESSAGE_FILE_MES)){
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
ManageServerConnectClientThread.getServerConnectClientThread(userId).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
} else{
System.out.println("其他类型的message,暂时不处理...");
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
8.ServerPushNewsThread.java
package com.tangguanlin.service;
import com.tangguanlin.common.Message;
import com.tangguanlin.common.MessageType;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;
public class ServerPushNewsThread extends Thread{
@Override
public void run() {
while (true){
System.out.println("请输入要推送的新闻:");
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
Message message = new Message();
message.setMesType(MessageType.MESSAGE_NEWS_MES);
message.setContent(next);
HashMap<String, ServerConnectClientThread> hashmap = ManageServerConnectClientThread.getHashmap();
Set<String> keySet = hashmap.keySet();
for(String userId:keySet){
if(!userId.equals(message.getSender())){
ObjectOutputStream objectOutputStream = null;
try {
objectOutputStream = new ObjectOutputStream( ManageServerConnectClientThread.getServerConnectClientThread(userId).getSocket().getOutputStream());
objectOutputStream.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
|