- socket套接字
用于描述ip地址和端口号,是一个通讯链的句柄(java的应用)在internet上的一个主句,一般运行多个服务器的软件,
同时就提供多个服务,每个服务监听一个端口,不同的端口对应的不同的服务
最终应用程序和服务器通过socket套接字建立网络连接,发送和接收请求
-
服务端套接字:
-
客户端套接字:
就不多说了,直接看代码吧,写的一个简单的文件上传和下载功能,可能不是很成熟,希望能对你有帮助
/**
* 服务端
* @author PC
*/
public class Server {
public static void main(String[] args) throws Exception {
// 创建ServerSocket对象
ServerSocket ss = new ServerSocket(9991);
System.out.println("服务器已经启动...");
while (true) {
// 开始监听9991端口
Socket s = ss.accept();
// 仅代表run逻辑
ThreadHandler th = new ThreadHandler(s);
Thread t = new Thread(th);
t.start();
}
}
}
/**
* 服务端线程
* @author PC
*/
public class ThreadHandler implements Runnable {
private Socket socket;
public ThreadHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 下载文件
// 获取客户端ip地址
InetAddress ip = socket.getInetAddress();
// 构建网络输入流
DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
// 构建网络输出流
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
// 接收传过来的操作
String cz = dis.readUTF();
if (cz != null && "1".equals(cz)) {
ServerDownload sd = new ServerDownload();
sd.getServerDownload(dis, dos);
} else if (cz != null && "2".equals(cz)) {
SeverUpload su = new SeverUpload();
su.getServerUpload(dis, dos);
} else {
System.out.println("传入序号有误!!!");
}
// 关闭流
dos.close();
dis.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 此类是服务端的上传功能
* @author PC
*/
public class SeverUpload {
public void getServerUpload(DataInputStream dis, DataOutputStream dos) {
try {
// 接收客户端传过来的文件姓名和大小
String fileName = dis.readUTF();
String length = dis.readUTF();
System.out.println("fileName=" + fileName + " length=" + length);
// 构建本地输出流
DataOutputStream dos_local = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("D:/download/" + fileName)));
// 创建一个缓存
byte[] buf = new byte[1024 * 4];
int len = -1;
while (true) {
if (dis != null) {
len = dis.read(buf);
}
if (len == -1) {
break;
}
dos_local.write(buf, 0, len);
dos_local.flush();
System.out.println("传输中...");
}
dos_local.close();
System.out.println("server传输完毕!!!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 服务器端的下载
* @author PC
*/
public class ServerDownload {
public void getServerDownload(DataInputStream dis, DataOutputStream dos) {
try {
// 获取客户端传过来的地址
String filePath = dis.readUTF();
// 寻找指定的文件
File file = new File(filePath);
if (!file.exists()) {
// 如果所找文件不存在
dos.writeUTF("请求文件不存在,请重新输入:");
dos.flush();
} else {
// 文件存在,那么获取文件名和大小
String fileName = file.getName();
// 把文件名称写到网络上
dos.writeUTF(fileName);
dos.flush();
// 把文件大小写到网络上
long length = file.length();
dos.writeUTF(length + "");
dos.flush();
// 准备发送文件
System.out.println("准备发送文件给...");
// 构建本地输入流
DataInputStream dis_local = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
// 构建缓冲
byte[] buf = new byte[1024 * 4];
int len = -1;
// 将文件读到内存,在从内存写到网络上
while (true) {
if (dis_local != null) {
// 读到内存
len = dis_local.read(buf);
}
if (len == -1) {
break;
}
// 写到网络上
dos.write(buf, 0, len);
dos.flush();
System.out.println("传输中...");
}
dis_local.close();
}
System.out.println("server传输完毕!!!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 客户端
* @author PC
*/
public class Client {
public static void main(String[] args) throws Exception {
try {
int i = 1;
while (true) {
// 构建Socket对象(Ip地址,端口号),相当于连接服务器
Socket socket = new Socket("localhost", 9991);
// 构建网络输出流
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
// 构建网络输入流
DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
Scanner input = new Scanner(System.in);
System.out.println("请输入要执行的操作的序号:1.下载/2.上传");
String cz = input.next();
// 把输入的序号传给服务端
dos.writeUTF(cz);
dos.flush();
// 判断序号是1.下载还是2.上传
if (cz != null && "1".equals(cz)) {
ClientDownload cd = new ClientDownload();
cd.getClientDownload(dos, dis);
} else if (cz != null && "2".equals(cz)) {
ClientUpload cu = new ClientUpload();
cu.getClientDownload(dos, dis);
} else {
System.out.println("输入操作序号错误,请重新输入:");
if (i == 3) {
System.out.println("三次错误!请重启!");
break;
}
i++;
}
dis.close();
dos.close();
socket.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 此类写客户端的上传功能
* @author PC
*/
public class ClientUpload {
public void getClientDownload(DataOutputStream dos, DataInputStream dis) {
try {
Scanner input = new Scanner(System.in);
// 接收要上传的文件路径
System.out.println("请输入要上传的文件路径:");
String filePath = input.next();
File file = new File(filePath);
if (!file.exists()) {
System.out.println("文件未找到");
} else {
// 把文件名和文件大小上传
String fileName = file.getName();
dos.writeUTF(fileName);
dos.flush();
long length = file.length();
dos.writeUTF(length + "");
dos.flush();
// 构建本地输入流
DataInputStream dis_local = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
// 创建缓存
byte[] buf = new byte[1024 * 4];
int len = -1;
System.out.println("文件开始传输...");
while (true) {
if (dis_local != null) {
len = dis_local.read(buf);
}
if (len == -1) {
break;
}
dos.write(buf, 0, len);
dos.flush();
System.out.println("传输中...");
}
dis_local.close();
System.out.println("client文件传输完毕!!!");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 此类写客户端的下载
* @author PC
*/
public class ClientDownload {
public void getClientDownload(DataOutputStream dos, DataInputStream dis) {
try {
Scanner input = new Scanner(System.in);
// 接收输入的地址
System.out.println("请输入要下载的文件地址:");
String filePath = input.next();
// 把地址传到网络流
dos.writeUTF(filePath);
dos.flush();
// 接收文件的名字和大小
String fileName = dis.readUTF();
String length = dis.readUTF();
System.out.println("文件名字:" + fileName + " length:" + length);
// 构建本地输出流
DataOutputStream dos_local = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("d:/download/" + fileName)));
// 构建一个缓冲
byte[] buf = new byte[1024 * 4];
System.out.println("开始接收文件...");
int len = -1;
// 循环从网络上把数据读入内存,再把内存文件写到硬盘
while (true) {
if (dis != null) {
len = dis.read(buf);
}
if (len == -1) {
break;
}
dos_local.write(buf, 0, len);
dos_local.flush();
System.out.println("文件下载中..");
}
dos_local.close();
System.out.println("client文件传输完毕!!!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}