杂谈socket编程

本文介绍了Socket在网络编程中的核心作用,通过一张图解释了TCP的三次握手过程。接着,展示了使用Java实现的简单FTP服务器和客户端代码,包括服务器的监听、客户端连接、文件传输等功能,详细解释了每个关键步骤和代码逻辑。
摘要由CSDN通过智能技术生成

 最近在写一些与网络编程相关的小工具,不得不再把网络编程的知识再回顾回顾了。一提起网络编程,势必局想到了一位核心人物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);
    

更多详见:http://www.mark-to-win.com/tutorial/50313.html


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值