socket通常也称作"套接字",实现服务器和客户端之间的物理连接,并进行数据传输,主要有UDP和TCP两个协议。Socket处于网络协议的传输层。下面通过具体的例子来说明socket的一些常见用法。(下载请见底部)
Android客户端/java客户端
代码:
package com.example.eric.mylibrary;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;
/**
* 发送文件
* Created by Eric_ on 2018/7/22.
*/
public class SocketDemo {
public static void main(String[] a){
final String path = "xxxx";//文件路径
final String fileName = "xxxx";//文件名称
final String ipAddress = "xxxx";//服务器ip地址
final int port = xxxx;//服务器开放端口
Thread sendThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(FileSend(fileName, path, ipAddress, port));
}
});
sendThread.start();
}
public static String FileSend(String fileName, String path, String ipAddress, int port){
try {
Socket socket = new Socket(ipAddress, port);//设置socket,并进行连接connect
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];//数据存储
// 选择进行传输的文件
File file = new File(path + fileName);
System.out.println("文件长度:" + (int) file.length());
DataInputStream input = new DataInputStream(new FileInputStream(path + fileName));
DataOutputStream output = new DataOutputStream(socket.getOutputStream());//将socket设置为数据的传输出口
DataInputStream getAck = new DataInputStream(socket.getInputStream());//设置socket数据的来源
//将文件名传输过去
output.writeUTF(file.getName());
output.flush();
//将文件长度传输过去
output.writeLong((long) file.length());
output.flush();
int readSize = 0;
while(true)
{
if(input != null)
{
readSize = input.read(buf);
}
if(readSize == -1)
break;
output.write(buf, 0, readSize);
if(!getAck.readUTF().equals("OK"))
{
System.out.println("服务器"+ ipAddress + ":" + port + "失去连接!");
break;
}
}
output.flush();// 注意关闭socket链接,不然客户端会等待server的数据过来,// 直到socket超时,导致数据不完整。
input.close();
output.close();
socket.close();
getAck.close();
System.out.println("文件传输完成");
return fileName + " 发送完成";
} catch (Exception e) {
return "发送错误:\n" + e.getMessage();
}
}
}
服务器:
代码:
package com.example.eric.mylibrary;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务端,接受文件
* Created by Eric_ on 2018/7/22.
*/
public class AcceptSocketFile {
static boolean isEnable;
private static ServerSocket server;
static int port = xxxx;
public static void main(String[] a) {
final String path = "xxxx"; //接受文件路径
// 服务器端用于监听Socket的线程
Thread listener = new Thread(new Runnable() {
@Override
public void run() {
try {
server = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
if (server != null) {
while (true) {
ReceiveFile(path);
}
}
}
});
listener.start();
}
public static String ReceiveFile(String path) {
try {
Socket socket = server.accept();
System.out.println("客户端"+ socket.getInetAddress() +"已连接");
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];//数据存储
long donelen = 0;//传输完成的数据长度
long filelen = 0;//文件长度
//将socket数据作为数据输入流
DataInputStream input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
//以客户端的IP地址作为存储路径
String fileDir = path + "\\" + socket.getInetAddress().toString().substring(1, socket.getInetAddress().toString().length());;
File file = new File(fileDir);
//判断文件夹是否存在,不存在则创建
if(!file.exists())
{
file.mkdir();
}
String fileName = input.readUTF();//读取文件名
//设置文件路径
String filePath = fileDir + "\\" + fileName;
file = new File(filePath);
if(!file.exists())
{
file.createNewFile();
}
DataOutputStream fileOut = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(file)));
filelen = input.readLong();//读取文件长度
System.out.println("文件的长度为:" + filelen + "\n");
System.out.println("开始接收文件!" + "\n");
DataOutputStream ack = new DataOutputStream(socket.getOutputStream());
while (true) {
int read = 0;
if (input != null) {
read = input.read(buf);
ack.writeUTF("OK");//结束到数据以后给client一个回复
}
if (read == -1) {
break;
}
donelen += read;
// 下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
System.out.println("文件接收了" + (donelen * 100 / filelen)
+ "%\n");
fileOut.write(buf, 0, read);
}
if(donelen == filelen)
System.out.println("接收完成,文件存为" + file + "\n");
else
{
System.out.printf("IP:%s发来的%s传输过程中失去连接\n",socket.getInetAddress(),fileName);
file.delete();
}
ack.close();
input.close();
fileOut.close();
return fileDir+"接受完成";
} catch (Exception e) {
return "接收错误:\n" + e.getMessage();
}
}
}
备注:如果是租的服务器,最好通过官网来开启端口,通过Linux指令开启的端口,在某些平台上有限制。文件传输的格式没有要求。
版权声明:--------------------------------------------博文可随意转载,但请注明出处,谢谢!-------------------------------------------- https://blog.csdn.net/weixin_42474261/article/details/81182375