zoukankan      html  css  js  c++  java
  • Socket简单实现数据交互及上传

      

    声明:本文为原创,如需转载请说明出处:http://www.cnblogs.com/gudu1/p/7669175.html 

      首先为什么要写这个呢?因为在几个月之前我还使用Socket做一个小项目,而在今天我回想起Socket的操作细节,在我脑海里使劲挖掘Socket的痕迹,竟然丝毫没有找到,所以立即写了一个小Demo来记录一下,有些东西长时间不用肯定要忘的,人的脑容量有限,跟电脑缓存一样,不够用的时候会把那些不用的占内存的给释放掉, 就到这吧,说正题。

        Socket 和 ServerSocket 的官方API解释:

        Socket : 此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。

        ServerSocket:此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

      套接字的实际工作由 SocketImpl 类的实例执行。应用程序通过更改创建套接字实现的套接字工厂可以配置它自身,以创建适合本地防火墙的套接字。

      在这个Demo中我使用了java.net包下的两个类:Socket 和 ServerSocket ,使用到的自定义类有3个:Service 、 Client 、ServiceThread,下面配合代码来解释一下

      ServiceThread.java ,就把它当做一个服务器处理程序就好了

    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.io.IOException;
    import java.io.*;
    public class ServiceThread implements Runnable {
        Socket s = null;
        
        public ServiceThread(Socket socket) { // ①
            super();
            this.s = socket;
        }
    
        @Override
        public void run() {
            String ip = s.getInetAddress().getHostName(); // ②
            System.out.println("ip:"+ip); 
            try{
                InputStream is = s.getInputStream(); // ③
                byte[] buf = new byte[1024];
                int len = 0;    
                File file = new File("D:/heheCopy.java"); // ④
                OutputStream os = new FileOutputStream(file);
                System.out.println("开始上传");
                while((len = is.read(buf)) != -1){ // ⑤
                    os.write(buf,0,len);  // ⑥
                }    
                System.out.println("上传完毕");
                is.close();
                os.close();
            } catch (Exception e){
                e.printStackTrace();
            }
            
        }
    }

      

       ① :类只有一个构造函数,参数是Socket对象(即一个用户),因为在服务器和客户端是通过 I/O 流来交互,所以服务器端要获取客户端的IO对象(即输入输出流)。

      ②: 获取客户端的IP地址

      ③: 获取客户端的输入流,

      ④: 创建一个File对象,并指定客户端传输过来的数据存放的位置,如果不存在该文件就自动创建

      ⑤: 开始从流中读取数据,并存放在byte数组缓冲区中,在客户端的输出流未写入之前此方法一直处于阻塞状态(即等待状态)

      ⑥: 开始写入服务器本地文件

      Client.java ,当做一个客户端

    public class Client {
        public static void main(String[] args) throws Exception {
            Socket s = new Socket("127.0.0.1", 10001);  // ①
            InputStream is = new FileInputStream("D:/hehe.java"); // ②
            byte[] buf = new byte[1024];
            int len = 0;
            while((len = is.read(buf))!=-1){
                s.getOutputStream().write(buf,0,len); // ③
            }
            s.shutdownOutput(); // ④
            System.out.println("读取完毕");
            is.close();
        }
    }

       ①: 创建 Socket 对象,传入要连接服务器的 IP 和 端口

      ②: 创建一个输入流对象读取要上传的文件路径

      ③: 获取 Socket 输出流对象并将读取到的数据写入输出流中

      ④: 任何以前写入的数据都将被发送,如果不调用这个方法,那么在服务器端就不会知道数据已经传输完毕,将继续调用此 Socket 输入流的 read 方法,那么此时客户端只是一个Java程序,已经执行完毕,虚拟机将释放资源,这时,此Socket已经被 close掉,程序将抛出 SocketException 异常。

      Serivce.java ,服务器

    public class Service{
        public static void main(String[] args)throws Exception{
            ServerSocket ss = new ServerSocket(10001); // ①
            while(true){
                Socket s = ss.accept(); // ②
                new Thread(new ServiceThread(s)).start();  // ③
            }
        }
    }

      

      ①: 创建服务器对象,指定该服务器的端口号

      ②: 获得请求连接到该服务器的客户端对象Socket

      ③: 启动服务器处理程序线程,因为程序是无限循环,所以每当一个客户端连接进来都会创建一个新的线程

       

               The End。。。。。

  • 相关阅读:
    优化总结文章链接
    帧同步、状态同步
    ecs
    AStarPathFinding
    unity 热更方案对比
    C#数据类型
    JavaScript基础
    CSS中margin和padding的区别
    css选择器
    hadoop中使用shell判断HDFS文件是否存在
  • 原文地址:https://www.cnblogs.com/gudu1/p/7669175.html
Copyright © 2011-2022 走看看