<html>

文档版本号 开发工具 測试平台 project名字 日期 作者 备注
V1.0 2016.04.03 lutianfei none

第十二章网络编程

网络编程概述

  • 就是用来实现网络互连的不同计算机上执行的程序间能够进行数据交换。

网络模型

  • 计算机网络之间以何种规则进行通信,就是网络模型研究问题。

  • 网络模型通常是指
    • OSI(Open System Interconnection开放系统互连)參考模型
    • TCP/IP參考模型

网络模型7层概述

  • 1 . 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流

    这一层的数据叫做比特

  • 2 . 数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装解封装。常把这一层的数据叫做。在这一层工作的设备是交换机,数据通过交换机来传输。

  • 3 . 网络层:主要将从下层接收到的数据进行IP地址封装解封装。在这一层工作的设备是路由器,常把这一层的数据叫做数据包

  • 4 . 传输层:定义了一些数据传输的协议port号。

    主要是将从下层接收的数据进行分段传输。到达目的地址后再进行重组。经常把这一层数据叫做

    • TCP:传输控制协议,传输效率低可靠性强。用于传输可靠性要求高,数据量大的数据。

    • UDP:用户数据包协议,与TCP特性恰恰相反,用于传输可靠性要求不高数据量小的数据。
      • 如QQ聊天数据就是通过这样的方式传输的。
  • 5 . 会话层:通过传输层建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间须要互相认识能够是IP也能够是MAC或者是主机名)。

  • 6 . 表示层:主要是进行对接收的数据进行解释加密解密压缩解压缩等(把计算机能够识别的东西转换成人能够能识别的东西(如图片、声音等)。

  • 7 . 应用层: 主要是一些终端的应用。比方说FTP(各种文件下载),WEB(IE浏览),QQ之类的(能够把它理解成我们在电脑屏幕上能够看到的东西.就是终端应用)。

网络通信三要素

  • IP地址:InetAddress
    • 网络中设备的标识,不易记忆,可用主机名
  • port号
    • 用于标识进程的逻辑地址,不同进程的标识
  • 传输协议
    • 通讯的规则
    • 常见协议:TCP。UDP

网络通信模型

  • 第一个条件:我要先找到你 (IP)
  • 第二个条件:你得有接收数据的地方 耳朵 (port)
  • 第三个条件:我跟你说话,你能接收到,咱按什么方式接收啊,我说英文你懂吗,说韩文你懂吗,不懂是吧,所以我还是说中文把.(协议)

IP地址

  • 要想让网络中的计算机能够互相通信。必须为每台计算机指定一个标识号。通过这个标识号来指定要接受数据的计算机和识别发送的计算机,在TCP/IP协议中,这个标识号就是IP地址。

  • 怎样获取和操作IP地址呢?

    • 为了方便我们对IP地址的获取和操作,java提供了一个类InetAddress

  • 所谓IP地址就是给每一个连接在Internet上的主机分配的一个32bit地址。依照TCP/IP规定,IP地址用二进制来表示,每一个IP地址长32bit,比特换算成字节。就是4个字节。IP地址的这样的表示法叫做“点分十进制表示法”,这显然比1和0easy记忆得多。

IP地址的组成
  • IP地址 = 网络号码+主机地址

  • A类IP地址 : 第一段号码为网络号码剩下的三段号码为本地计算机的号码

  • B类IP地址:前二段号码为网络号码剩下的二段号码为本地计算机的号码
  • C类IP地址:前三段号码为网络号码剩下的一段号码为本地计算机的号码

  • 特殊地址:

    • 127.0.0.1 回环地址,可用于測试本机的网络是否有问题。
      • eg : ping 127.0.0.1
    • xxx.xxx.xxx.0 网络地址
    • xxx.xxx.xxx.255 广播地址
InetAddress类的使用
  • 没有构造方法,那么怎样使类提供的功能呢?
  • 要掌握的方法
    • 获取随意主机:getByName
    • 主机名:getHostName
    • 主机Ip地址:getHostAddress

port号

  • 物理port 网卡口
  • 逻辑port 我们指的就是逻辑port
    • A:每一个网络程序都会至少有一个逻辑port
    • B:用于标识进程的逻辑地址,不同进程的标识
    • C:有效port:0~65535,当中0~1024系统使用或保留port。
    • 通过360能够查看port号

协议UDP和TCP

UDP
  • 数据源目的封装成数据包中,不须要建立连接;每一个数据报的大小在限制在64k。因无连接,是不可靠协议;不须要建立连接。速度快
  • 举例:
    • 聊天留言。在线视频,视频会议。发短信,邮局包裹。
TCP
  • 建立连接,形成数据传输的通道;在连接中进行大数据量传输。通过三次握手完毕连接,是可靠协议;必须建立连接效率会稍低
  • 举例:
    • 下载,打电话。QQ聊天(你在线吗,在线,就回应下,就開始聊天了)


Socket编程

  • 又称网络编程套接字编程
  • Socket套接字:
    • 网络上具有唯一标识的IP地址port号组合在一起才干构成唯一能识别的标识符套接字。
  • Socket原理机制:
    • 通信的两端都有Socket。
    • 网络通信事实上就是Socket间的通信。

    • 数据在两个Socket间通过IO传输。


UDP传输过程

  • DatagramSocketDatagramPacket
  • 建立发送端接收端

  • 建立数据包
  • 调用Socket的发送接收方法。

  • 关闭Socket。
  • 发送端与接收端是两个独立的执行程序。

UDP传输-发送端思路

  • 1:建立udp的socket服务
  • 2:将要发送的数据封装成数据包
  • 3:通过udp的socket服务,将数据包发送出
  • 4:关闭资源

  • UDP传输-发送端代码

/*
 * UDP协议发送数据:
 * A:创建发送端Socket对象
 * B:创建数据,并把数据打包
 * C:调用Socket对象的发送方法发送数据包
 * D:释放资源
 */
public class SendDemo {
    public static void main(String[] args) throws IOException {
        // 创建发送端Socket对象
        // DatagramSocket()
        DatagramSocket ds = new DatagramSocket();

        // 创建数据,并把数据打包
        // DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        // 创建数据
        byte[] bys = "hello,udp,我来了".getBytes();
        // 长度
        int length = bys.length;
        // IP地址对象
        InetAddress address = InetAddress.getByName("192.168.12.92");
        // port
        int port = 10086;
        DatagramPacket dp = new DatagramPacket(bys, length, address, port);

        // 调用Socket对象的发送方法发送数据包
        // public void send(DatagramPacket p)
        ds.send(dp);

        // 释放资源
        ds.close();
    }
}


UDP传输-接收端思路

  • 1:建立udp的socket服务.
  • 2:通过receive方法接收数据
  • 3:将收到的数据存储到数据包对象中
  • 4:通过数据包对象的功能来完毕对接收到数据进行解析.
  • 5:能够对资源进行关闭

  • UDP传输-接收端代码

/*
 * UDP协议接收数据:
 * A:创建接收端Socket对象
 * B:创建一个数据包(接收容器)
 * C:调用Socket对象的接收方法接收数据
 * D:解析数据包,并显示在控制台
 * E:释放资源
 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        // 创建接收端Socket对象
        // DatagramSocket(int port)
        DatagramSocket ds = new DatagramSocket(10086);

        // 创建一个数据包(接收容器)
        // DatagramPacket(byte[] buf, int length)
        byte[] bys = new byte[1024];
        int length = bys.length;
        DatagramPacket dp = new DatagramPacket(bys, length);

        // 调用Socket对象的接收方法接收数据
        // public void receive(DatagramPacket p)
        ds.receive(dp); // 堵塞式

        // 解析数据包。并显示在控制台
        // 获取对方的ip
        // public InetAddress getAddress()
        InetAddress address = dp.getAddress();
        String ip = address.getHostAddress();
        // public byte[] getData():获取数据缓冲区
        // public int getLength():获取数据的实际长度
        byte[] bys2 = dp.getData();
        int len = dp.getLength();
        String s = new String(bys2, 0, len);
        System.out.println(ip + "传递的数据是:" + s);

        // 释放资源
        ds.close();
    }
}


  • 优化后代码
/*
 * 多次启动接收端:
 *         java.net.BindException: Address already in use: Cannot bind
 *         port被占用。
 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        // 创建接收端的Socket对象
        DatagramSocket ds = new DatagramSocket(12345);

        // 创建一个包裹
        byte[] bys = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys, bys.length);

        // 接收数据
        ds.receive(dp);

        // 解析数据
        String ip = dp.getAddress().getHostAddress();
        String s = new String(dp.getData(), 0, dp.getLength());
        System.out.println("from " + ip + " data is : " + s);

        // 释放资源
        ds.close();
    }
}




public class SendDemo {
    public static void main(String[] args) throws IOException {
        // 创建发送端的Socket对象
        DatagramSocket ds = new DatagramSocket();

        // 创建数据并打包
        byte[] bys = "helloworld".getBytes();
        DatagramPacket dp = new DatagramPacket(bys, bys.length,
                InetAddress.getByName("192.168.12.92"), 12345);

        // 发送数据
        ds.send(dp);

        // 释放资源
        ds.close();
    }
}


UDP案例

  • 从键盘录入数据进行发送,假设输入的是886那么client就结束输入数据。
/*
 * 多次启动接收端:
 *         java.net.BindException: Address already in use: Cannot bind
 *         port被占用。

*/ public class ReceiveDemo { public static void main(String[] args) throws IOException { // 创建接收端的Socket对象 DatagramSocket ds = new DatagramSocket(12345); while (true) { // 创建一个包裹 byte[] bys = new byte[1024]; DatagramPacket dp = new DatagramPacket(bys, bys.length); // 接收数据 ds.receive(dp); // 解析数据 String ip = dp.getAddress().getHostAddress(); String s = new String(dp.getData(), 0, dp.getLength()); System.out.println("from " + ip + " data is : " + s); } // 释放资源 // 接收端应该一直开着等待接收数据,是不须要关闭 // ds.close(); } } /* * 数据来自于键盘录入 * 键盘录入数据要自己控制录入结束。 */ public class SendDemo { public static void main(String[] args) throws IOException { // 创建发送端的Socket对象 DatagramSocket ds = new DatagramSocket(); // 封装键盘录入数据 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = null; while ((line = br.readLine()) != null) { if ("886".equals(line)) { break; } // 创建数据并打包 byte[] bys = line.getBytes(); // DatagramPacket dp = new DatagramPacket(bys, bys.length, // InetAddress.getByName("192.168.12.92"), 12345); DatagramPacket dp = new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.12.255"), 12345); // 发送数据 ds.send(dp); } // 释放资源 ds.close(); } }


  • 把刚才发送和接收程序分别用线程进行封装,完毕一个UDP的聊天程序。

/*
 * 通过多线程改进刚才的聊天程序。这样我就能够实如今一个窗体发送和接收数据了
 */
public class ChatRoom {
    public static void main(String[] args) throws IOException {
        DatagramSocket dsSend = new DatagramSocket();
        DatagramSocket dsReceive = new DatagramSocket(12306);

        SendThread st = new SendThread(dsSend);
        ReceiveThread rt = new ReceiveThread(dsReceive);

        Thread t1 = new Thread(st);
        Thread t2 = new Thread(rt);

        t1.start();
        t2.start();
    }
}




public class ReceiveThread implements Runnable {
    private DatagramSocket ds;

    public ReceiveThread(DatagramSocket ds) {
        this.ds = ds;
    }

    @Override
    public void run() {
        try {
            while (true) {
                // 创建一个包裹
                byte[] bys = new byte[1024];
                DatagramPacket dp = new DatagramPacket(bys, bys.length);

                // 接收数据
                ds.receive(dp);

                // 解析数据
                String ip = dp.getAddress().getHostAddress();
                String s = new String(dp.getData(), 0, dp.getLength());
                System.out.println("from " + ip + " data is : " + s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}



public class SendThread implements Runnable {

    private DatagramSocket ds;

    public SendThread(DatagramSocket ds) {
        this.ds = ds;
    }

    @Override
    public void run() {
        try {
            // 封装键盘录入数据
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    System.in));
            String line = null;
            while ((line = br.readLine()) != null) {
                if ("886".equals(line)) {
                    break;
                }

                // 创建数据并打包
                byte[] bys = line.getBytes();
                // DatagramPacket dp = new DatagramPacket(bys, bys.length,
                // InetAddress.getByName("192.168.12.92"), 12345);
                DatagramPacket dp = new DatagramPacket(bys, bys.length,
                        InetAddress.getByName("192.168.12.255"), 12306);

                // 发送数据
                ds.send(dp);
            }

            // 释放资源
            ds.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}


TCP传输

  • Socket和ServerSocket
  • 建立client和server端
  • 建立连接后。通过Socket中的IO流进行数据的传输
  • 关闭socket
  • 相同。client与server端是两个独立的应用程序。

TCP传输-client思路

  • 1:建立client的Socket服务,并明白要连接的server。
  • 2:假设连接建立成功,就表明已经建立了数据传输的通道。就能够在该通道通过IO进行数据的读取和写入。该通道称为Socket流,Socket流中既有读取流,也有写入流
  • 3:通过Socket对象的方法,能够获取这两个流。
  • 4:通过流的对象能够对数据进行传输
  • 5:假设数据传输完毕,关闭资源

  • TCP传输-client代码

/*
 * 连接被拒绝。

TCP协议一定要先开server。 * java.net.ConnectException: Connection refused: connect */ public class ClientDemo { public static void main(String[] args) throws IOException { // 创建发送端的Socket对象 // Socket(InetAddress address, int port) // Socket(String host, int port) // Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888); Socket s = new Socket("192.168.12.92", 8888); // 获取输出流。写数据 // public OutputStream getOutputStream() OutputStream os = s.getOutputStream(); os.write("hello,tcp,我来了".getBytes()); // 释放资源 s.close(); } }


TCP传输-server端思路

  • 1:建立server端的socket服务,须要一个port
  • 2:服务端没有直接流的操作,而是通过accept方法获取client对象,再通过获取到的client对象的流和client进行通信。
  • 3:通过client的获取流对象的方法,读取数据或者写入数据
  • 4:假设服务完毕,须要关闭client,然后关闭server,可是,通常会关闭client,不会关闭server,由于服务端是一直提供服务的。

  • TCP传输-server端代码

/*
 * TCP协议接收数据:
 * A:创建接收端的Socket对象
 * B:监听client连接。返回一个相应的Socket对象
 * C:获取输入流。读取数据显示在控制台
 * D:释放资源
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建接收端的Socket对象
        // ServerSocket(int port)
        ServerSocket ss = new ServerSocket(8888);

        // 监听client连接。返回一个相应的Socket对象
        // public Socket accept()
        Socket s = ss.accept(); // 侦听并接受到此套接字的连接。

此方法在连接传入之前一直堵塞。

// 获取输入流,读取数据显示在控制台 InputStream is = s.getInputStream(); byte[] bys = new byte[1024]; int len = is.read(bys); // 堵塞式方法 String str = new String(bys, 0, len); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "---" + str); // 释放资源 s.close(); // ss.close(); //这个不应该关闭 } }


TCP传输案例

  • server给client反馈
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建serverSocket对象
        ServerSocket ss = new ServerSocket(9999);

        // 监听client的连接
        Socket s = ss.accept(); // 堵塞

        // 获取输入流
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys); // 堵塞
        String server = new String(bys, 0, len);
        System.out.println("server:" + server);

        // 获取输出流
        OutputStream os = s.getOutputStream();
        os.write("数据已经收到".getBytes());

        // 释放资源
        s.close();
        // ss.close();
    }
}


public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建clientSocket对象
        Socket s = new Socket("192.168.12.92", 9999);

        // 获取输出流
        OutputStream os = s.getOutputStream();
        os.write("今天天气非常好,适合睡觉".getBytes());

        // 获取输入流
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);// 堵塞
        String client = new String(bys, 0, len);
        System.out.println("client:" + client);

        // 释放资源
        s.close();
    }
}


  • client键盘录入。server输出到控制台
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建serverSocket对象
        ServerSocket ss = new ServerSocket(22222);

        // 监听client连接
        Socket s = ss.accept();

        // 包装通道内容的流
        BufferedReader br = new BufferedReader(new InputStreamReader(
                s.getInputStream()));
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

        // br.close();
        s.close();
        // ss.close();
    }
}



/*
 * client键盘录入,server输出到控制台
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建clientSocket对象
        Socket s = new Socket("192.168.12.92", 22222);

        // 键盘录入数据
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // 把通道内的流给包装一下
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                s.getOutputStream()));

        String line = null;
        while ((line = br.readLine()) != null) {
            // 键盘录入数据要自己定义结束标记
            if ("886".equals(line)) {
                break;
            }
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        // 释放资源
        // bw.close();
        // br.close();
        s.close();
    }
}


  • client键盘录入,server输出文本文件
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建serverSocket对象
        ServerSocket ss = new ServerSocket(23456);

        // 监听client连接
        Socket s = ss.accept();

        // 封装通道内的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(
                s.getInputStream()));
        // 封装文本文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));

        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        bw.close();
        // br.close();
        s.close();
        // ss.close();
    }
}


  • client文本文件,server输出到控制台
/*
 * client文本文件,server输出到控制台
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建Socket对象
        Socket s = new Socket("192.168.12.92", 34567);

        // 封装文本文件
        BufferedReader br = new BufferedReader(new FileReader(
                "InetAddressDemo.java"));
        // 封装通道内的流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                s.getOutputStream()));

        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        br.close();
        s.close();
    }
}




public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建serverSocket对象
        ServerSocket ss = new ServerSocket(34567);

        // 监听client连接
        Socket s = ss.accept();

        // 封装通道内的流
        BufferedReader br = new BufferedReader(new InputStreamReader(
                s.getInputStream()));

        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }


        s.close();
    }
}


TCP传输easy出现的问题

  • client连接上服务端,两端都在等待,没有不论什么数据传输。
  • 通过例程分析:
    • 由于read方法或者readLine方法是堵塞式。
  • 解决的方法:
    • 自己定义结束标记
    • 使用shutdownInput。shutdownOutput方法。
  • client文本文件。server输出文本文件
/*
 * 问题:依照我们正常的思路增加反馈信息,结果却没反应。

为什么呢?

* 读取文本文件是能够以null作为结束信息的,可是呢,通道内是不能这样结束信息的。 * 所以。server根本就不知道你结束了。而你还想server给你反馈。

所以,就相互等待了。

* * 怎样解决呢? * A:再多写一条数据,告诉server,读取到这条数据说明我就结束,你也结束吧。 * 这样做能够解决这个问题。可是不好。 * B:Socket对象提供了一种解决方式 * public void shutdownOutput() */ public class UploadClient { public static void main(String[] args) throws IOException { // 创建clientSocket对象 Socket s = new Socket("192.168.12.92", 11111); // 封装文本文件 BufferedReader br = new BufferedReader(new FileReader( "InetAddressDemo.java")); // 封装通道内流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter( s.getOutputStream())); String line = null; while ((line = br.readLine()) != null) { // 堵塞 bw.write(line); bw.newLine(); bw.flush(); } //Socket提供了一个终止。它会通知server你别等了,我没有数据过来了 s.shutdownOutput(); // 接收反馈 BufferedReader brClient = new BufferedReader(new InputStreamReader( s.getInputStream())); String client = brClient.readLine(); // 堵塞 System.out.println(client); // 释放资源 br.close(); s.close(); } } public class UploadServer { public static void main(String[] args) throws IOException { // 创建server端的Socket对象 ServerSocket ss = new ServerSocket(11111); // 监听client连接 Socket s = ss.accept();// 堵塞 // 封装通道内的流 BufferedReader br = new BufferedReader(new InputStreamReader( s.getInputStream())); // 封装文本文件 BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java")); String line = null; while ((line = br.readLine()) != null) { // 堵塞 // if("over".equals(line)){ // break; // } bw.write(line); bw.newLine(); bw.flush(); } // 给出反馈 BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter( s.getOutputStream())); bwServer.write("文件上传成功"); bwServer.newLine(); bwServer.flush(); // 释放资源 bw.close(); s.close(); } }


  • 上传图片案例
public class UploadServer {
    public static void main(String[] args) throws IOException {
        // 创建serverSocket对象
        ServerSocket ss = new ServerSocket(19191);

        // 监听client连接
        Socket s = ss.accept();

        // 封装通道内流
        BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
        // 封装图片文件
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("mn.jpg"));

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
            bos.flush();
        }

        // 给一个反馈
        OutputStream os = s.getOutputStream();
        os.write("图片上传成功".getBytes());

        bos.close();
        s.close();
    }
}




    public static void main(String[] args) throws IOException {
        // 创建clientSocket对象
        Socket s = new Socket("192.168.12.92", 19191);

        // 封装图片文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                "林青霞.jpg"));
        // 封装通道内的流
        BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
            bos.flush();
        }

        s.shutdownOutput();

        // 读取反馈
        InputStream is = s.getInputStream();
        byte[] bys2 = new byte[1024];
        int len2 = is.read(bys2);
        String client = new String(bys2, 0, len2);
        System.out.println(client);

        // 释放资源
        bis.close();
        s.close();
    }
}


  • server的代码用线程进行封装,这样能够模拟一个同一时候接收多人上传文件的server。(用循环也能够可是效率低,是单线程的程序)
public class UploadClient {
    public static void main(String[] args) throws IOException {
        // 创建clientSocket对象
        Socket s = new Socket("192.168.12.92", 11111);

        // 封装文本文件
        // BufferedReader br = new BufferedReader(new FileReader(
        // "InetAddressDemo.java"));
        BufferedReader br = new BufferedReader(new FileReader(
                "ReceiveDemo.java"));
        // 封装通道内流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                s.getOutputStream()));

        String line = null;
        while ((line = br.readLine()) != null) { // 堵塞
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        // Socket提供了一个终止,它会通知server你别等了。我没有数据过来了
        s.shutdownOutput();

        // 接收反馈
        BufferedReader brClient = new BufferedReader(new InputStreamReader(
                s.getInputStream()));
        String client = brClient.readLine(); // 堵塞
        System.out.println(client);

        // 释放资源
        br.close();
        s.close();
    }
}





public class UserThread implements Runnable {
    private Socket s;

    public UserThread(Socket s) {
        this.s = s;
    }

    @Override
    public void run() {
        try {
            // 封装通道内的流
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    s.getInputStream()));
            // 封装文本文件
            // BufferedWriter bw = new BufferedWriter(new
            // FileWriter("Copy.java"));

            // 为了防止名称冲突
            String newName = System.currentTimeMillis() + ".java";
            BufferedWriter bw = new BufferedWriter(new FileWriter(newName));

            String line = null;
            while ((line = br.readLine()) != null) { // 堵塞
                bw.write(line);
                bw.newLine();
                bw.flush();
            }

            // 给出反馈
            BufferedWriter bwServer = new BufferedWriter(
                    new OutputStreamWriter(s.getOutputStream()));
            bwServer.write("文件上传成功");
            bwServer.newLine();
            bwServer.flush();

            // 释放资源
            bw.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}



public class UploadServer {
    public static void main(String[] args) throws IOException {
        // 创建serverSocket对象
        ServerSocket ss = new ServerSocket(11111);

        while (true) {
            Socket s = ss.accept();
            new Thread(new UserThread(s)).start();
        }
    }
}


版权声明:本文为博主原创文章,未经博主同意不得转载。

举报

  • 本文已收录于下面专栏:

相关文章推荐

好用的在线 java 编译站点(亲測)

在网上搜了不少在线编译站点,国内外都有。对于java来说。我感觉最好用的是这个: http://www.browxy.com/ 它不仅执行速度快,并且还能保存代码。

其它有的站点要么不能保存代码,要么...

网页版在线聊天java Socket实现

注:本文引用地址http://www.jb51.net/article/84689.htm 本文为大家分享了一个满足在线网页交流需求的实例。因为java Socket实现的网页版...

Java web项目 在线网络考试考生登录界面部分代码

网络在线考试 function check(form){ if (form.name.value==""){ alert("请输入准考证号!");form.name.focus();retu...

java Socket实现简单在线聊天(三)

在上一篇,利用线程使服务端实现了可以接收多client请求的功能,这里便须要client接收多client消息的同一时候还能把消息转发到每一个连接的client,而且client要能在内容显示区域显示出来,从而实现简单的在线群聊。 ...

【JavaWeb】关于WebSocket的IM在线聊天技术(一)

近期在弄IM的在线聊天。发现layim又停摆了,所下面决心看看曾经学的socket技术。这次的想法是不用swing,使用javaweb的jsp实如今线聊天。 我计划的大致实现步骤分这样几大步: 1...
  • hj7jay
  • hj7jay
  • 2016-05-19 10:13
  • 7334

Java web项目 在线网络考试加入管理员部分代码

加入管理员信息 function check(form){ if(form.name.value==""){ alert("请输入管理员名称!");form.name.focus();r...

java Socket实现简单在线聊天(一)

近期的项目有一个在线网页交流的需求,因为非常久曾经做过的demo已经忘记的差点儿相同了,因此便又一次学习一下。

我计划的大致实现步骤分这样几大步: 1、使用awt组件和socket实现简单的单client向服务...

java程序使用HttpURLConnection连接互联网(完好中)

使用这个之前要对HTTP报文有所了解: HTTP报文具体解释:http://www.oschina.net/question/565065_81309

java 从零開始,学习笔记之基础入门<网络编程_带QQ模拟功能>(二十)

网络编程 port: 计算机为特定的程序提供的一个入口。那么我们通过port就能够连接到相应的程序上去 Ip:是用来标示网络中唯一的主机地址 常见的Tcpport与相应的服务(协议) port</span

黑马程序猿学习log第八篇基础知识:JAVA的面向对象之网络编程总结

黑马程序猿学习log第八篇基础知识:JAVA的面向对象之网络编程总结 ---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----...
  • 微博
    微信
    QQ
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多仅仅同意输入30个字)

posted @ 2017-08-14 18:20  yjbjingcha  阅读(228)  评论(0)    收藏  举报