【TCP协议练习】服务端利用多线程TCP同时接受多个客户端发送文件

   程序实现的是一个读取照片(可改成其文件类型)的服务端,可同时接受多个客户端链接,而且同时接受多张图片的数据。主要是经过多线程控制,每次检测到有请求链接,则开辟一个新线程,新线程的做用是接受图片, 经过不一样线程同时运行达到可同时接收多张图片。java

1. 这是服务端的源代码:服务器

import java.io.*;
import java.net.*;
public class LoadPicServer {
    public static void main(String[] args) throws IOException {
        int listen_port = 10005;      //监听的端口号
        long filecount = 1;      
        ServerSocket ss = new ServerSocket(listen_port);          //监听listen_port端口
        if(ss.isBound())
            System.out.println("The Server is listenning the port " + listen_port);
        while(true) {
            Socket s = ss.accept();   //检查是否有链接,该语句是阻塞语句,若是没有则会停在这。
            if(s.isConnected()) {    //若是有链接则返回true,执行下面语句
                String filename = new String("ServerPic" + filecount++ + ".jpg");
                System.out.println(s.getInetAddress().getHostAddress()
                                    + " is connected!");                //获取已链接的客户端的IP
                new Thread(new LoadPic(s,filename)).start();            //开启新线程接收图片,主线程继续回去while最开始检查有无链接。
            }
        }
    }
}
/*
 * 该类实现Runnable接口,用于实现多线程复制图片。
 * 该类的做用就是与主线程传入的Socket链接进行通讯,从网络流获取对方的传送的文件数据。
 * */
class LoadPic implements Runnable {
    Socket s = null;
    String filename = null;
    BufferedInputStream bufin = null;
    BufferedOutputStream bufout = null;
    PrintWriter return_txt = null;
                                                                                                                                      
    public LoadPic(Socket s,String filename) {
        this.s = s;
        this.filename = filename;
    }
                                                                                                                                      
    public void run() { 
        try {
            bufin = new BufferedInputStream(s.getInputStream());                  //获取传入Socket的输入流,用于读取图片数据
            bufout = new BufferedOutputStream(new FileOutputStream(filename));    //在当前文件夹建立名为filename的文件,做为输出流的目的。
            return_txt = new PrintWriter(new OutputStreamWriter(s.getOutputStream()),true); //该流用来向客户端发送确认信息。
            byte[] bufdata = new byte[1024];
            int len;
            while((len = bufin.read(bufdata)) != -1) {              //从输入流读取数据,不为-1,即文件结束则继续读。
                bufout.write(bufdata,0,len);                         //往文件里写数据
                bufout.flush();
            }
                                                                                                                                              
            return_txt.println("服务器接收成功!");
                                                                                                                                              
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                s.close();
                bufin.close();
                bufout.close();
                return_txt.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


2. 这是客户端源代码,可同时开启多个客户端,作图片并行传输测试。由于多个客户端代码基本同样,因此只需看下面代码便可:网络


import java.net.*;
import java.io.*;
//该类是客户端类,向服务器段发送请求链接,链接后就能够发送图片数据。
class UpPicClient {
    public static void main(String[] args) throws IOException,InterruptedException {
        Socket s = new Socket("192.168.1.7",10005);
        if(s.isBound()) {
            System.out.println("Connect successful!");
            BufferedInputStream bufin = new BufferedInputStream(new FileInputStream("1.jpg"));
            BufferedOutputStream bufout = new BufferedOutputStream(s.getOutputStream());
            BufferedInputStream confirm_txt = new BufferedInputStream(s.getInputStream());
            byte[] bufdata = new byte[1024];
            int len;
            while((len = bufin.read(bufdata)) != -1) {
                bufout.write(bufdata,0,len);
                bufout.flush();
            }
            s.shutdownOutput();
            System.out.println("发送结束!");
            len = confirm_txt.read(bufdata,0,bufdata.length);
            String str = new String(bufdata,0,len);
            System.out.println(str);
            s.close();
            bufin.close();
            bufout.close();
            confirm_txt.close();
        }
    }
}