关于TCP以及UDP的相关知识,在此就不做相关总结,如有需要可以参考https://blog.csdn.net/li_ning_/article/details/52117463
package com.tcp.multithreadingTcp;
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
package com.tcp.multithreadingTcp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class LoginServer {
public static void main(String[] args) throws IOException {
//创建一个ServerSocket,指定监听的端口
ServerSocket serverSocket = new ServerSocket(8888);
int i = 0;
while (true) {
//使用ServerSocket监听用户请求
Socket socket = serverSocket.accept();//如果没有请求则阻塞
//启动一个登录线程
new Thread(new LoginThread(socket)).start();
System.out.println("你是访问该服务器的第" + ++i + "个用户,你的ip地址为"
+ socket.getInetAddress().getHostAddress());
socket.close();
}
}
}
package com.tcp.multithreadingTcp;
import java.io.*;
import java.net.Socket;
public class LoginThread implements Runnable {
private Socket socket;
LoginThread(Socket socket) {
this.socket = socket;
}
//处理用户请求
@Override
public void run() {
//接收来自客户端的数据并输出
try {
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
User user = (User) objectInputStream.readObject();
System.out.println(user.toString());
//发送反馈
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
if ("zhangsan".equals(user.getUsername()) && "1234".equals(user.getPassword())) {
dataOutputStream.writeUTF("登录成功");
} else {
dataOutputStream.writeUTF("登录失败");
}
//关闭资源
dataOutputStream.close();
objectInputStream.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
package com.tcp.multithreadingTcp;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class LoginClient {
public static void main(String[] args) throws IOException {
//创建一个Socket,指定服务器端的ip与端口
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
Scanner sc = new Scanner(System.in);
System.out.print("请输入用户名:");
String username = sc.nextLine();
System.out.print("请输入密码:");
String password = sc.nextLine();
User user = new User();
user.setUsername(username);
user.setPassword(password);
//发送登录信息
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(user);
//接收数据
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
String res = dataInputStream.readUTF();
System.out.println(res);
//关闭资源
dataInputStream.close();
inputStream.close();
objectOutputStream.close();
outputStream.close();
socket.close();
}
}
运行结果:(客户端)
请输入用户名:zhangsan
请输入密码:1234
登录成功
运行结果:(服务端)
User{username='zhangsan', password='1234'}
你是访问该服务器的第1个用户,你的ip地址为xxx.xxx.xxx.xxx
UDP相较于TCP实现简单一些,所以代码量也稍微的少一些
package com.udp.moreThanOneUdp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/**
* 功能:在线客服.
* 技能:使用UDP网络编程完成
* 注意
* 1. UDP编程中客户端和服务器端区分不明显,双方代码差别不大
* 2.主动发起请求的一段是客户端,接收请求的是服务器端;一旦通信开始,客户端和服务器端无差别
* 3.不涉及IO流
* 4.主要API
* - DatagramSocket:socket,作用是发送和接收DatagramPacket
* - DatagramPacket:数据报(封装数据,目的地址,源地址,端口号)
*/
public class AskServer {
public static void main(String[] args) throws IOException {
//创建一个DatagramSocket,用来发送和接收数据
DatagramSocket socket = new DatagramSocket(8888);//服务器端接收数据的端口
Scanner sc = new Scanner(System.in);
while (true) {
//使用DatagramSocket接收一个DatagramPacket
byte[] buf = new byte[1024];
DatagramPacket datagramPacket1 = new DatagramPacket(buf, buf.length);
socket.receive(datagramPacket1);
System.out.println("对方说:" + new String(datagramPacket1.getData(), 0, datagramPacket1.getLength()));
//使用DatagramSocket发送一个DatagramPacket
System.out.print("请您输入:");
String info = sc.nextLine();
InetAddress inetAddress = datagramPacket1.getAddress();
int port = datagramPacket1.getPort();
DatagramPacket datagramPacket2 = new DatagramPacket(info.getBytes(), info.getBytes().length, inetAddress, port);
socket.send(datagramPacket2);
if (info.equals("bye")) {
break;
}
}
System.out.println("聊天结束");
//关闭资源
socket.close();
}
}
package com.udp.moreThanOneUdp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class AskClient {
public static void main(String[] args) throws IOException {
//创建一个DatagramSocket,用来发送和接收数据
DatagramSocket socket = new DatagramSocket(8889);//客户端接收数据的端口,可以省略,会自动分配
Scanner sc = new Scanner(System.in);
while (true) {
//使用DatagramSocket发送一个DatagramPacket
System.out.print("请您输入:");
String info = sc.nextLine();
InetAddress inetAddress = InetAddress.getLocalHost();
DatagramPacket datagramPacket1 = new DatagramPacket(info.getBytes(), info.getBytes().length, inetAddress, 8888);
socket.send(datagramPacket1);
if (info.equals("bye")) {
break;
}
//使用DatagramSocket接收一个DatagramPacket
byte[] buf = new byte[1000];
DatagramPacket datagramPacket2 = new DatagramPacket(buf, buf.length);
socket.receive(datagramPacket2);
System.out.println("对方说:" + new String(buf, 0, datagramPacket2.getLength()));
}
System.out.println("聊天结束");
//关闭资源
socket.close();
}
}
运行结果:(客户端)
请您输入:你好呀
对方说:你是谁
请您输入:我是张三,你呢
对方说:我是李四
请您输入:好的,我要忙了
对方说:bye
请您输入:bye
聊天结束
运行结果:(服务端)
对方说:你好呀
请您输入:你是谁
对方说:我是张三,你呢
请您输入:我是李四
对方说:好的,我要忙了
请您输入:bye
聊天结束
- 文件上传的本质:文件从客户端到服务器端的复制
- 文件下载的本质:文件从服务器端到客户端的复制
- 文件的上传和下载都是两次文件复制
package com.tcp.uploadTcp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class UploadServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
//创建一个输入流和一个输出流
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File("/test1.txt")));
//使用输入流和输出流完成文件复制
//中转站
int n;
//读取末尾的一个字节的内容赋给n
n = bufferedInputStream.read();
while (n != -1){
//写一个字节
bufferedOutputStream.write(n);
System.out.println(1);
//读一个字节
n = bufferedInputStream.read();
}
//关闭资源
bufferedInputStream.close();
bufferedOutputStream.close();
socket.close();
serverSocket.close();
}
}
package com.tcp.uploadTcp;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class UploadClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(),8888);
//创建一个输入流和一个输出流
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("/test.txt")));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
//关闭资源
bufferedInputStream.close();
bufferedOutputStream.close();
socket.close();
}
}
package com.tcp.downloadTcp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class DownloadServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
//创建一个输入流和一个输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File("/test.txt")));
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
//使用输入流和输出流完成文件复制
//中转站
int n;
//读取末尾的一个字节的内容赋给n
n = bufferedInputStream.read();
while (n != -1){
//写一个字节
bufferedOutputStream.write(n);
//读一个字节
n = bufferedInputStream.read();
}
//关闭资源
bufferedInputStream.close();
bufferedOutputStream.close();
socket.close();
serverSocket.close();
}
}
package com.tcp.downloadTcp;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class DownloadClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(),8888);
//创建一个输入流和一个输出流
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File("/test1.txt")));
//关闭资源
bufferedInputStream.close();
bufferedOutputStream.close();
socket.close();
}
}
其实上传功能和下载功能的逻辑是相同的,只不过一个是文件c => s,一个是文件s => c
参考视频:https://www.bilibili.com/video/av31123719/