通信,实际上就是服务器与客户端之间的数据交互,其中的所有过程都是把传出与得到的数据进行处理二进行其他操作。因此,除了这部分之外,最关键的部分就是通信协议了。通信协议,贫僧认为它就好比两者之间所共同遵守的规定,它告诉了参与通信的机器传输数据以及读取数据的方式
服务器代码(含有多线程内容)
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); } }