【Java小项目】一个Socket连续传输多个文件

摘要:
想给前短时间做的那个山寨QQ加一个传输文件的功能,因为那个山寨QQ每个客户端和服务器端就一个Socket连接用ObjectOutputStream进行通信,现在要加一个DataOutputStream来传输文件,所以先了写这个试验下。思路:1.在发送DataOutputStream字节流前先发一个Object来通知接受端。

想给前短时间做的那个山寨QQ加一个传输文件的功能,因为那个山寨QQ每个客户端和服务器端就一个Socket连接用ObjectOutputStream进行通信,现在要加一个DataOutputStream来传输文件,所以先了写这个试验下。

思路:

1.在发送DataOutputStream字节流前先发一个Object来通知接受端。

2.用writeLong通知接收端该文件的长度。

3.用writeUTF发送文件名称

4.接受端用接受到的文件长度来跳出读文件的循环

5.(缺点)接收文件的时候不能在接收Object信息

代码如下

Server

package com.server;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by ztc on 15-11-16.
 */
public class MyServer extends JFrame implements ActionListener{
    ServerSocket ss=null;
    Socket s=null;

    JFileChooser jfc;
    JButton jb,jb1;
    JTextArea jta;
    ObjectOutputStream oos;
    public static void main(String[] args){
        MyServer ms=new MyServer(8888);
        //ms.SendFile();
    }
    public MyServer(int port) {
        jfc=new JFileChooser();
        jb=new JButton("传输文件");
        jb.addActionListener(this);
        jb1=new JButton("SendObject!");
        jb1.addActionListener(this);
        jta=new JTextArea();
        jta.setEditable(false);
        jta.setAutoscrolls(true);
        this.add(jta,"Center");
        this.add(jb,"South");
        this.add(jb1,"North");

        this.setVisible(true);
        this.setLocation(500,300);
        this.setSize(300,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        try {
            ss=new ServerSocket(port);
            System.out.println("Server is running...on"+port);
            s=ss.accept();
            oos=new ObjectOutputStream(s.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public void SendFile(File f,Object o){
        try {
            oos.writeObject(o);
            oos.flush();

            DataInputStream dis=new DataInputStream(new FileInputStream(f));
            DataOutputStream dos=new DataOutputStream(s.getOutputStream());
            //ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
            //oos.writeObject(f);
            dos.writeLong(f.length());
            dos.writeUTF(f.getName());
            System.out.println("长度:"+f.length());
            int count=-1,sum=0;
            byte[] buffer=new byte[1024*1024];
            while((count=dis.read(buffer))!=-1){
                dos.write(buffer,0,count);
                sum+=count;
                System.out.println("以传输"+sum+"byte");
            }
            System.out.println("发送完毕!");
            dos.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void SendObject(Object o){
        try {
            oos.writeObject(o);
            oos.flush();
            System.out.println("Sended Object!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==jb){
            jfc.setCurrentDirectory(jfc.getCurrentDirectory());
            int result=jfc.showOpenDialog(this);
            File f=jfc.getSelectedFile();
            if(result==0&&f!=null){
                SendFile(f,"File");
            }
        }else if(e.getSource()==jb1){
            SendObject("hello Im Server!");
        }
    }
}

Client

package com.client;

import java.io.*;
import java.net.Socket;

/**
 * Created by ztc on 15-11-16.
 */
public class MyClient{
    static Socket s = null;
    public static void main(String[] args) {
        MyClient my=new MyClient("127.0.0.1", 8888);
    }

    public MyClient(String host, int port) {

        try {
            s=new Socket(host,port);
            System.out.println("Data running>>>");
            ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
            while (true) {
                String type=(String)ois.readObject();
                System.out.println(type);
                if(type.equals("File")){
                    new FileTransport(s).run();
                }
                System.out.println("Object接受完毕!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

工具类

package com.client;

import java.io.*;
import java.net.Socket;

/**
 * Created by ztc on 15-11-17.
 */
public class FileTransport {
    Socket s;
    public FileTransport(Socket s){
        this.s=s;
    }
    public void run(){
        try {
            System.out.println("Thread running>>>");
            DataInputStream dis = new DataInputStream(s.getInputStream());
            long length=dis.readLong();
            String name=dis.readUTF();
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File(name)));
            int count=-1,sum=0;
            byte[] buffer=new byte[1024*1024];
            while((count=dis.read(buffer))!=-1){
                dos.write(buffer,0,count);
                sum+=count;
                System.out.println("已结收" + sum + "比特");
                if(sum==length)
                    break;
            }
            dos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

免责声明:文章转载自《【Java小项目】一个Socket连续传输多个文件》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇安装Oracle11后在SQL Developer启动时提示:enter the full pathname for the java.exe转-VS2010常用功能使用介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vite尝鲜-最新代码原理分析

使用webpack在开发中,只改动一句代码,也需要数秒的热更新,这是因为webpack需要将所有的模块打包成一个一个或者多个模块,然后启动开发服务器,请求服务器时直接给予打包结果。这个过程随着项目的扩大,速度会变慢。然后vite来了。 描述:针对Vue单页面组件的无打包开发服务器,可以直接在浏览器运行请求的vue文件 特点: 冷服务启动-使用ES6 im...

前端基础总结

HTML初识 △HTML: 超文本标记语言,是一种用于创建网页的标记语言,不是编程语言,没有逻辑 本质上是浏览器可识别的规则 我们按照规则写网页,浏览器根据规则渲染我们的网页。对于不同的浏览器,对同一个标签可能会有不同的解释。(兼容性问题) 网页文件的扩展名:.html或.htm(没有区别) 网页文件的扩展名:.html或.htm(没有区别) 我们按照规则...

Linux Socket学习(十二)

套接口选项在前面的几章中,我们讨论了使用套接口的基础内容。现在我们要来探讨一些可用的其他的特征。在我们掌握了这一章的概念之后,我们就为后面的套接口的高级主题做好了准备。在这一章,我们将会专注于下列主题:如何使用getsockopt(2)函数获得套接口选项值如何使用setsockopt(2)函数设置套接口选项值如何使用这些常用的套接口选项得到套接口选项有时,...

[Socket网络编程]一个封锁操作被对 WSACancelBlockingCall 的调用中断。

原文地址:http://www.cnblogs.com/xiwang/archive/2012/10/25/2740114.html记录在此,方便查阅。 C#中在使用UDPClient循环监听端口,在断开UPDClient的时候,使用try...catch捕获了异常,System.NET.Sockets.SocketException“一个封锁操作被对...

[Linux] 多进程网络编程监听一个端口

SO_REUSEPORT支持多个进程或者线程绑定到同一端口 每个进程可以自己创建socket、bind、listen、accept相同的地址和端口,各自是独立平等的。让多进程监听同一个端口,各个进程中accept socket fd不一样,有新连接建立时,内核只会唤醒一个进程来accept,并且保证唤醒的均衡性 <?php $context=str...

用C#实现Web代理服务器3

  9.创建Proxy类中的Run方法。Run方法是Proxy类中唯一的方法。其功能是从客户端接收HTTP请求,并传送到Web服务器,然后从Web服务器接收反馈来的数据,并传送到客户端。为了实现这二个不同方面的数据传送,Run方法中是通过两个Socket实例来实现的。在编写Run方法的时候,要注意下面两点:   (1)由于HTTP建立于TCP协议之上,所以...