socket传输文件时,只能通过流去读取消息。当socket接收文件、消息等不同的数据时,如何区别是字符串还是流是很重要的。为了保证接收到的数据类型统一(数据是字符串还是流),需要定义协议。定义协议的方式有很多种:
1.发送一个握手信号。 根据握手信号来确定发送的是字符串还是流
2.定义了Header(头)和Body(实体),头是固定大小的,用来告诉接收者数据的格式、用途、长度等信息,接收者根据Header 来接受Body。
3.自定义协议。
这里采用自定义协议,统一传输JSON数据,根据字段标识传输的是字符串还是流,接收者根据标识去解析数据即可。
协议的实体类(Transmission):
public class Transmission implements Parcelable {
/**
* 文件名称
*/
public String fileName;
/**
*文件长度
*/
public long fileLength;
/**
*传输类型
*/
public int transmissionType;
/**
*传输内容
*/
public String content;
/**
*传输长度
*/
public long transLength;
public Transmission(){
}
protected Transmission(Parcel in){
this.fileName = in.readString();
this.fileLength = in.readLong();
this.transmissionType = in.readInt();
this.content = in.readString();
this.transLength = in.readLong();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.fileName);
dest.writeLong(this.fileLength);
dest.writeInt(this.transmissionType);
dest.writeString(this.content);
dest.writeLong(this.transLength);
}
public static final Creator<Transmission> CREATOR = new Creator<Transmission>() {
@Override
public Transmission createFromParcel(Parcel in) {
return new Transmission(in);
}
@Override
public Transmission[] newArray(int size) {
return new Transmission[size];
}
};
}
根据字段transmissionType去标识传输(序列化)或者接收(发序列化)的类型。传输的过程中始终都是以JSON的格式存在的。在传输文件时需要把流转换成字符串(Base64加密与解密)。
客户端(ClientThread)
public class RemoteClientSocket extends Thread {
private Gson mGson;
private PrintWriter mPrintWriter;