服务端和客户端无限通信(需要线程)(基于TPC协议的网络编程)
Cilent
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 9000);
System.out.println("客户端连接");
//接收服务器的信息
InputStream inputStream = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
//给服务器发送数据
OutputStream outputStream = socket.getOutputStream();
//控制台输入信息
Scanner input= new Scanner(System.in);
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
new ReadThread(bis).start();
while(true) {
String next = input.next();
bos.write(next.getBytes());
bos.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Server
public class Server {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(9000);
System.out.println("等待连接");
//连接客户端
Socket socket = server.accept();
System.out.println("连接成功");
//获取输出流对象
OutputStream outputStream = socket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
//获取客户端的信息
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
//控制台输入信息
Scanner input = new Scanner(System.in);
new ReadThread(bis).start();
while(true) {
String next = input.next();
bos.write(next.getBytes());
bos.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ReadThread线程
public class ReadThread extends Thread {
BufferedInputStream bis;
public ReadThread(BufferedInputStream bis) {
super();
this.bis = bis;
}
@Override
public void run() {
while(true) {
int i=0;
byte[] b =new byte[1024];
try {
while((i=bis.read(b))!=-1) {
String str = new String(b,0,i);
System.out.println(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
效果图
Server
Client
服务端向客户端群发(基于TPC协议的网络编程)
Client(开启三个,代码都一样)
public class Client1 {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1",9000);
System.out.println("客户端连接......");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
new ReadThread(in).start();
}
}
Server
public class Server {
//创建集合存储客户端的socket
static List<Socket> collections = new ArrayList<>();
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(9000);
System.out.println("等待连接");
Scanner input =new Scanner(System.in);
// 加线程 为了遍历取出connections中的socket
new QunFaThread(input).start();
while(true){
//开始连接客户端
Socket socket = server.accept();
System.out.println("连接的客户端:"+socket);
//存储客户端的socket
collections.add(socket);
System.out.println("集合中的元素------"+collections);
//获取客户端发来的信息
// BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
}
public static void sendAll(String s) throws Exception{
if(null != collections){
for (int i = 0; i < collections.size(); i++) {
Socket socket = collections.get(i);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println(s);
pw.flush();
}
}
}
}
ReadThread
public class ReadThread extends Thread{
BufferedReader br;
public ReadThread(BufferedReader br) {
super();
this.br = br;
}
public void run() {
while(true){
try {
String readLine = br.readLine();
System.out.println(readLine);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
QunFaThread
public class QunFaThread extends Thread{
Scanner input;
public QunFaThread(Scanner input) {
super();
this.input = input;
}
public void run() {
while(true){
String s = input.nextLine();
try {
Server.sendAll(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
效果图:
客户端向客户端群发(基于TPC协议的网络编程)
客户端–服务端–客户端
Client(开启三个客户端)
public class Client1 {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1",9000);
System.out.println("客户端连接......");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream());
Scanner input = new Scanner(System.in);
new ReadThread(in).start();
while(true){
pw.println(input.nextLine());
pw.flush();
}
}
}
Server
public class Server {
//创建集合存储客户端的socket
static List<Socket> collections = new ArrayList<>();
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(9000);
System.out.println("等待连接");
Scanner input =new Scanner(System.in);
while(true){
//开始连接客户端
Socket socket = server.accept();
System.out.println("连接的客户端:"+socket);
//存储客户端的socket
collections.add(socket);
System.out.println("集合中的元素------"+collections);
new QunFaThread(socket).start();
}
}
public static void sendAll(String s) throws Exception{
if(null != collections){
for (int i = 0; i < collections.size(); i++) {
Socket socket = collections.get(i);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println(s);
pw.flush();
}
}
}
}
ReadThread
public class ReadThread extends Thread{
BufferedReader br;
public ReadThread(BufferedReader br) {
super();
this.br = br;
}
public void run() {
while(true){
try {
String readLine = br.readLine();
System.out.println(readLine);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
QunFaThread
public class QunFaThread extends Thread{
Socket socket;
public QunFaThread( Socket socket) {
super();
this.socket = socket;
}
public void run() {
while(true){
//得到输入流
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = br.readLine();
Server.sendAll(s);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
效果图:
客户端和客户端的私聊(基于TPC协议的网络编程)
Client
public class Client1 {
public static void main(String[] args) throws UnknownHostException, IOException {
//输入自己的名称
Scanner input = new Scanner(System.in);
System.out.println("请输入您的姓名:");
String name = input.next();
Socket socket = new Socket("127.0.0.1",9001);
//接收服务端发来的消息
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//将自己的姓名传过去
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println(name);
pw.flush();
new ReadThread(br).start();
while(true) {
//给服务端发送消息
PrintWriter pw2 = new PrintWriter(socket.getOutputStream());
pw2.println(input.next());
pw2.flush();
}
}
}
Server
public class Server {
static ArrayList<Socket> socketList = new ArrayList<>();
static ArrayList<QunFaThread> threadList = new ArrayList<>();
public static void main(String[] args) throws Exception {
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(9001);
System.out.println("等待连接");
while(true) {
//连接客户端
Socket socket = serverSocket.accept();
socketList.add(socket);
System.out.println("连接成功-----------------------"+socket);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//获取客户端的名字
String name = br.readLine();
QunFaThread qf = new QunFaThread(name,socket);
threadList.add(qf);
//开启线程
qf.start();
}
}
//群发
public static void sendAll(String str) throws IOException {
if(null!=socketList) {
for (int i = 0; i < socketList.size(); i++) {
Socket socket = socketList.get(i);
//向所有的客户端发送消息
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println(str);
pw.flush();
}
}
else {
System.out.println("没有客户端连接服务器");
}
}
//私聊
public static void sendOne(String fromName,String toName,String line) throws IOException {
if(null!=socketList) {
for (int i = 0; i < socketList.size(); i++) {
QunFaThread qf = threadList.get(i);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(qf.getSocket().getOutputStream()));
if(qf.getFromName().equals(toName)){
pw.println(line);
pw.flush();
}
else {
System.out.println("查无此人");
}
}
}
}
}
ReadThread
public class ReadThread extends Thread {
BufferedReader br;
public ReadThread(BufferedReader br) {
super();
this.br = br;
}
public void run() {
while (true) {
try {
String readLine = br.readLine();
System.out.println(readLine);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
QunFaThread
public class QunFaThread extends Thread{
String fromName;
Socket socket;
public QunFaThread(String fromName, Socket socket) {
super();
this.fromName = fromName;
this.socket = socket;
}
public String getFromName() {
return fromName;
}
public void setFromName(String fromName) {
this.fromName = fromName;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
while(true) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//获取客户端发来的信息
String readLine = br.readLine();
//@one@xiaoming@nihao
if(readLine.startsWith("@one")) {
//私聊
String[] s = readLine.split("@");
Server.sendOne(fromName, s[2], s[3]);
}
else {
//群发
Server.sendAll(readLine);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
效果图
关闭Socket
Socket的close()方法,关闭socket的同时也会关闭由socket创建的流
调用流的close方法关闭socket获取的输入或输出流的同时,也会关闭对应的socket。
UPD协议
定义: UDP协议是提供非连接的、面向事务的、简单不可靠的通信服务的传输层协议
基于UDP协议的网络编程:
DatagramSocket
定义:用于发送和接收数据报包的套接字
构造方法:
DatagramSocket ds=new DatagramSocket();
DatagramSocket ds=new DatagramSocket(int prot);//端口号
DatagramSocket ds=new DatagramSocket(int port, InetAddress laddr);//端口号 ip地址
方法:
DatagramPacket
包含要发送或接收的数据
包含数据报发送或接收的地址信息
构造方法
DatagramPacket dp = DatagramPacket(byte[ ] data, int length) //数据 数据长度
DatagramPacket dp = DatagramPacket(byte[ ] data, int offset, int length)//数据 数据偏移量 数据长度
DatagramPacket dp = DatagramPacket(byte[ ] data, int length, InetAddress remoteAddr, int remotePort)//数据 数据长度 目的ip地址 目的端口号
方法
服务端给客户端发送消息(基于UDP协议的网络通信)
Server
public class Server {
@SuppressWarnings("resource")
public static void main(String[] args) throws SocketException, Exception {
//创建套接字
DatagramSocket ds = new DatagramSocket();
//要发送的数据
String str="你好,我是服务端";
//创建要发送的数据报包,传入要发送的数据,数据长度,目的ip地址及端口号
DatagramPacket datagramPacket = new DatagramPacket(str.getBytes(), str.length(),InetAddress.getByName("127.0.0.1"),7788);
//发送数据
ds.send(datagramPacket);
//释放资源
ds.close();
}
}
Client
public class Client {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
//创建套接字,端口号7788
DatagramSocket ds = new DatagramSocket(7788);
//创建DatagramPacket对象,用于接收数据
DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
//等待接收数据,没有数据则阻塞
ds.receive(dp);
String str = new String(dp.getData(),0,dp.getLength());
//打印接收到的信息
System.out.println(str+"来自"+dp.getAddress()+"-----"+dp.getPort());
ds.close();
}
}
效果图
服务端和客户端即时通信(UDP协议网络通信)
Server
public class Server {
public static void main(String[] args) throws Exception {
//创建发送套接字
DatagramSocket sendsocket = new DatagramSocket(10000);
//创建接收套接字
DatagramSocket recesocket = new DatagramSocket(9000);
//准备目的主机的IP地址
InetAddress address = InetAddress.getByName("localhost");
//发送线程建立 发送套接字,目的主机IP地址和目的主机用于接收的端口号
Send_Thread send_thread = new Send_Thread(sendsocket, address,8888);
//接收线程的建立
Receive_Thread rece_thread = new Receive_Thread(recesocket);
//启动线程
send_thread.start();
rece_thread.start();
}
}
Client
public class Client {
public static void main(String[] args) throws Exception {
//创建发送套接字
DatagramSocket sendsocket = new DatagramSocket(10001);
//创建接收套接字
DatagramSocket recesocket = new DatagramSocket(8888);
//准备目的主机的IP地址
InetAddress address = InetAddress.getByName("localhost");
//发送线程建立 //发送套接字,目的主机IP地址和目的主机用于接收的端口号
Send_Thread send_thread = new Send_Thread(sendsocket, address,9000);
//接收线程的建立
Receive_Thread rece_thread = new Receive_Thread(recesocket);
//启动线程
send_thread.start();
rece_thread.start();
}
}
Send_Thread
public class Send_Thread extends Thread {
//发送的socket端
private DatagramSocket sender = null;
//待发送的目标地址
private InetAddress address = null;
private int port; //监听端口
//从键盘输入
Scanner scan = new Scanner(System.in);
public Send_Thread(DatagramSocket sender,InetAddress address,int port)
{
this.sender = sender;
this.address = address;
this.port = port;
}
public void run(){
try{
while(true){
//输入待发送的内容
String input = scan.nextLine();
if(input.equals("exit"))
break;
byte[] data = null;
data = input.getBytes("UTF-8");
//构造数据报包对象
DatagramPacket pack = new DatagramPacket(data, data.length,address,port);
sender.send(pack);
}
System.out.println("Exit!");
}catch(IOException e){
}
}
}
Receive_Thread
public class Receive_Thread extends Thread {
private static final int MAX_RECEIVE_BUFFER = 1024;
private DatagramSocket server;
private DatagramPacket packet;
byte[] buffer = new byte[MAX_RECEIVE_BUFFER];
public Receive_Thread(DatagramSocket server){
this.server = server;
packet = new DatagramPacket(buffer, buffer.length);
}
public void run(){
while(true) {
//接收套接字负责接收数据包
try {
server.receive(packet);
//数据报包中获取数组格式的数据转为字符串格式
String s = new String(packet.getData(),packet.getOffset(),packet.getLength(),"UTF-8");
System.out.println(packet.getAddress()+":端口号"+packet.getPort()+"说 :"+s);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
效果图
UDP与TCP协议比较
优缺点比较
适用场景对比
TCP协议适用于对网络质量有要求的场景。比如文件传输,发送或接收邮件。
UDP协议适用于对网络通讯质量要求不高,但速度要快的场景。比如语音广播或视频。