最近在写一些与网络编程相关的小工具,不得不再把网络编程的知识再回顾回顾了。一提起网络编程,势必局想到了一位核心人物Socket,是她撑起了网络编程的半边天,使得网络编程得以继续。
什么是Socket?
通常也称作"套接字",应用程序通过Socket向网络发出请求或者应答网络请求。它是在应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,用来组织传输的数据。下面就用一张图来说明下“三次握手”:
网络间的通信,是建立在授受双方的,即:服务器与客户端。服务器端时刻处于启动状态,不停地监听着客户端发来的请求信息,并给予应答,当客户端向服务器发来一条数据请求时,服务器接受到了这条请求后,验证成功后,给出回复,建立链接通信,即一次握手。类似数据传输交换、断开链接又是两次握手。下面就以一段代码来做一分析说明吧。(Java版)
服务端:
<span style="font-size:14px;">import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * FTP服务器端 * @author xcbeyond * 2014-6-7 22:12:21 */ public class FtpServer { public static void main(String[] args) throws Exception{ FtpServer server = new FtpServer(); server.listen(8800); } //用来时刻监听来自客户端请求的监听者 public void listen(int port) throws Exception{ ServerSocket ss = new ServerSocket(port); while(true) { System.out.println("等待客户端连接..."); Socket socket = ss.accept(); System.out.println("客户连接进来了。"); new ClientAgent(socket).start(); } } class ClientAgent extends Thread{ Socket socket; InputStream in; OutputStream out; public ClientAgent(Socket socket) throws Exception{ this.socket = socket; in = socket.getInputStream(); out = socket.getOutputStream(); } @Override public void run() { BufferedReader in = new BufferedReader( new InputStreamReader(this.in)); PrintWriter out = new PrintWriter(this.out,true);//true自动清除缓存 相当于fulsh() try{ out.println("text,1"); out.println("你好欢迎使用FTP Demo!"); while(true) { String cmd = in.readLine(); if("?".equals(cmd)) { out.println("text,1"); out.println("支持命令:ls,get,?,bye"); } else if("ls".equals(cmd)) { listDir(out); } else if(cmd.matches("^get\\s+.+")) { sendFile(cmd,out,this.out); } else{ out.println("text,1"); out.println("不知可否!"); } } }catch(Exception e) { e.printStackTrace(); } } private void sendFile(String cmd, PrintWriter out,OutputStream os) throws IOException{ String name = cmd.split("\\s+")[1]; File file = new File(name); if(!file.exists()){ out.println("text,1"); out.println("没有找到文件! "+name); return; } out.println("file,"+file.length()+","+name); InputStream in = new BufferedInputStream( new FileInputStream(file)); int b; while((b = in.read())!=-1){ os.write(b); } os.flush(); in.close(); } /** * 列出文件目录 * @param out */ private void listDir(PrintWriter out) { File dir = new File("."); File[] files = dir.listFiles(new FileFilter() { public boolean accept(File pathname) { return pathname.isFile(); } }); out.println("text,"+files.length+1); out.println("在目录:"+dir+"中,有文件:"+files.length); for (File file : files) { out.println(file.getName()); } } } } </span>
客户端:
import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; /** * * @author xcbeyond * 2014-6-7 23:16:53 */ public class FtpClient { Socket socket; OutputStream out; InputStream in; public static void main(String[] args) throws Exception{ FtpClient client = new FtpClient(); client.open("localhost",8800); } public void open(String host,int port) throws Exception{ socket = new Socket(host,port); //对指定IP,端口的服务程序发出请求,建立通信 in = socket.getInputStream(); out =socket.getOutputStream(); new RequestSender(out).start(); new ResponseReceiver(in).start(); } class RequestSender extends Thread{ OutputStream out; public RequestSender(OutputStream out) { this.out = out; } @Override public void run() { PrintWriter out = new PrintWriter(this.out,true); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String str; try{ while((str = in.readLine())!=null) { out.println(str); } }catch(Exception e){ e.printStackTrace(); } } } class ResponseReceiver extends Thread { InputStream in; public ResponseReceiver(InputStream in) { this.in = in; } public void run() { BufferedReader in = new BufferedReader(new InputStreamReader(this.in)); try{ String str; while((str = in.readLine())!=null) { if(str.startsWith("text")) { String num = str.substring(str.indexOf(",")+1); printText(in,Integer.parseInt(num)); } else if(str.startsWith("file")){//file,4567,filename saveFile(this.in,str); } } }catch(Exception e) { e.printStackTrace(); } } /** * 保存文件 * @param in * @param size */ private void saveFile(InputStream in, String head) throws IOException{ String[] data = head.split(","); int length = Integer.parseInt(data[1]); String name = data[2]; OutputStream out = new BufferedOutputStream(new FileOutputStream("ftp-"+name)); for (int i = 0; i < length; i++) { int b = in.read(); out.write(b); } out.close(); System.out.println("下载了文件:"+name); } /** * 打印出文本内容 * @param in * @param num * @throws Exception */ private void printText(BufferedReader in, int num) throws Exception{ for (int i = 0; i < num; i++) { System.out.println(in.readLine()); } } } }