通信,实际上就是服务器与客户端之间的数据交互,其中的所有过程都是把传出与得到的数据进行处理二进行其他操作。因此,除了这部分之外,最关键的部分就是通信协议了。通信协议,贫僧认为它就好比两者之间所共同遵守的规定,它告诉了参与通信的机器传输数据以及读取数据的方式
服务器代码(含有多线程内容)
package 通信学习;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
Server server = new Server();
server.buildserver(8888);
}
//开启服务器端口
public void buildserver(int port){
try {
ServerSocket ss = new ServerSocket(port);
System.out.println("连接"+port+"端口成功");
while(true){
Socket sc = ss.accept();//类似前台接待员
System.out.println("客户端连接成功");
ServerThread st = new ServerThread(sc);
st.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package 通信学习;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ServerThread extends Thread{
private Socket sc;
public ServerThread(Socket sc) {
this.sc = sc;
}
//对信息的处理
public void run(){
try {
OutputStream os = sc.getOutputStream();
InputStream is = sc.getInputStream();
//用DataInputStream包装
DataInputStream dins = new DataInputStream(is);
while(true){
//读取消息长度
int length = dins.readInt();
//读取判断消息类型的标志
byte flag = dins.readByte();
//判断是普通聊天消息
if(flag == 1){
byte[] data = new byte[length-1-4];
dins.readFully(data);
String msg = new String(data);
System.out.println("发送内容为"+msg);
}
//判断是文件传输
else if(flag == 2){
System.out.println("服务器准备接收文件");
byte[] name = new byte[256];
dins.readFully(name);
//转换成字符串形式
String filename = new String(name);
//读取剩下的文件内容
byte[] data = new byte[length-1-4-256];
dins.readFully(data);
//保存文件
String allFileName="E:/"+filename;
File file = new File(allFileName.trim());
file.createNewFile();
FileOutputStream fops = new FileOutputStream(file);
fops.write(data);
fops.flush();
fops.close();
System.out.println("读取并保存文件成功");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
用于检测的客户端(需要特别注意与服务器之间的协议)
package 客户端;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class Chat {
//输出流对象全局化
private DataOutputStream dops;
//构建写入名字进流的方法
public void writeName(DataOutputStream ops,String filename,int len){
try {
byte[] data = filename.getBytes();
ops.write(data);
while(len>data.length){
ops.write('\0');
len--;
}
} catch (IOException e) {
e.printStackTrace();
}
}
//构建传文件的方法
public void sendfile(String filename){
try {
File file = new File(filename);
FileInputStream ips = new FileInputStream(file);
int filelength = ips.available();
int totallength = 4+1+256+filelength;
dops.writeInt(totallength);
dops.writeByte(2);
String shortfilename = file.getName().trim();
System.out.println(shortfilename);
writeName(dops,shortfilename,256);
byte[] filedata = new byte[filelength];
ips.read(filedata);
dops.write(filedata);
dops.flush();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//构建聊天的方法
public void sendmsg(String msg){
try {
byte[] str = msg.getBytes();
int totallength = 4+1+str.length;
dops.writeInt(totallength);
dops.writeByte(1);
dops.write(str);
dops.flush();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//连接到服务器的方法
public void conn(String ip,int port){
//添加窗口
JFrame jf = new JFrame("Robot");
//设置大小
jf.setBounds(400, 100, 500, 500);
//设置显示位置
jf.setLocationRelativeTo(null);
//设置关闭操作
jf.setDefaultCloseOperation(3);
//设置禁止改变大小
jf.setResizable(false);
//放一个对话框
JTextArea jta = new JTextArea();
jf.add(jta);
//窗口可视化
jf.setVisible(true);
try {
Socket client = new Socket(ip,port);//连接服务器
InputStream ips = client.getInputStream();//得到两者之间的输入流
OutputStream ops = client.getOutputStream();//得到两者之间的输出流
//用DataOutputStream包装
dops = new DataOutputStream(ops);
while(true){
if(jta.getText().indexOf("1") != -1){
sendmsg("Hello");
break;
}else if(jta.getText().indexOf("2") != -1){
System.out.println("客户端准备发送文件");
sendfile("G:/asd.txt");
break;
}
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//主函数
public static void main(String[] args) {
Chat cc = new Chat();
cc.conn("localhost", 8888);
}
}