TCP练习

【文本转换】


public class TransClient {

    /**
     * @param args
     * @throws IOException 
     * @throws UnknownHostException 
     */
    public static void main(String[] args) throws UnknownHostException, IOException {

        /*
         * 思路:
         * 客户端:
         * 1,需要先有socket端点。
         * 2,客户端的数据源:键盘。
         * 3,客户端的目的:socket.
         * 4,接收服务端的数据,源:socket。
         * 5,将数据显示在打印出来:目的:控制台.
         * 6,在这些流中操作的数据,都是文本数据。
         * 
         * 
         * 转换客户端:
         * 1,创建socket客户端对象。
         * 2,获取键盘录入。
         * 3,将录入的信息发送给socket输出流。
         */
        
        //1,创建socket客户端对象。
        Socket s = new Socket("192.168.1.100",10004);
        
        //2,获取键盘录入。
        BufferedReader bufr  =
                new BufferedReader(new InputStreamReader(System.in));
        
        //3,socket输出流。
//        new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        
        
        //4,socket输入流,读取服务端返回的大写数据
        BufferedReader bufIn  = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        String line = null;
        
        while((line=bufr.readLine())!=null){
            
            if("over".equals(line))
                break;
            
//            out.print(line+"\r\n");
//            out.flush();
            out.println(line);
            
            //读取服务端发回的一行大写数。
            String upperStr = bufIn.readLine();
            System.out.println(upperStr);
        }
        
        s.close();
        
    }

}

public class TransServer {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {

        /*
         * 
         * 转换服务端。
         * 分析:
         * 1,serversocket服务。
         * 2,获取socket对象。
         * 3,源:socket,读取客户端发过来的需要转换的数据。
         * 4,目的:显示在控制台上。
         * 5,将数据转成大写发给客户端。 
         */
        
        //1,
        ServerSocket ss = new ServerSocket(10004);
        
        //2,获取socket对象。
        Socket s = ss.accept();
        
        //获取ip.
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip+"......connected");
        
        //3,获取socket读取流,并装饰。 
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        //4,获取socket的输出流,并装饰。
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        
        String line = null;
        while((line=bufIn.readLine())!=null){
            
            System.out.println(line);
            out.println(line.toUpperCase());
//            out.print(line.toUpperCase()+"\r\n");//这里是为了演示阻塞造成的服务端和客户端都在等待的问题
//            out.flush();
        }
        
        s.close();
        ss.close();
        
    }

}


这里有个问题,当我们输入"over"时,发现服务端结束了。这是因为,客户端走到了s.close()方法,
这个时候socket关闭了,而服务端的readLine()方法是阻塞的,所以循环也会结束。

服务端和客户端都在等待的问题

如果把这行代码PrintWriter out = new PrintWriter(s.getOutputStream(),true);
改成PrintWriter out = new PrintWriter(s.getOutputStream())
再把out.println(line.toUpperCase());改成
PrintWriter out = new PrintWriter(s.getOutputStream())


这是因为PrintWriter out = new PrintWriter(s.getOutputStream())这句代码并没有把文本写入到Socket中,而PrintWriter out = new PrintWriter(s.getOutputStream())则会造成

服务端的readLine()读取不到结束标志,所以执行不到后面的代码。

【文件上传】


客户端:


public class UploadClient {

    /**
     * @param args
     * @throws IOException 
     * @throws UnknownHostException 
     */
    public static void main(String[] args) throws UnknownHostException, IOException {

        System.out.println("上传客户端。。。。。。");
        
        File file = new File("c:\\client.txt");
        System.out.println(file.exists());
        
        
        //1
        Socket s = new Socket("192.168.1.100",10005);
        
        //2
        BufferedReader bufr =
                new BufferedReader(new FileReader(file));
        
        //3,
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        
        
        String line = null;
        while((line=bufr.readLine())!=null){
            
            out.println(line);
        }
        
        //告诉服务端,客户端写完了。
        s.shutdownOutput();
//        out.println("!@#$%^&*(");
        
        //4,
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        String str = bufIn.readLine();
        System.out.println(str);
        
        bufr.close();
        s.close();
        
    }

}

服务端:


public class UploadServer {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        System.out.println("上传服务端。。。。。。。。。");
        
        //1
        ServerSocket ss = new ServerSocket(10005);
        
        //2,
        Socket s = ss.accept();
        
        System.out.println(s.getInetAddress().getHostAddress()+".....connected");
        
        //3,
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        //4,
        BufferedWriter bufw = new BufferedWriter(new FileWriter("c:\\server.txt"));
        
        String line = null;
        
        while((line=bufIn.readLine())!=null){
            
//            if("over".equals(line))
//                break;
            bufw.write(line);
            bufw.newLine();
            bufw.flush();
        }
        
        
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        out.println("上传成功");
        
        bufw.close();
        
        s.close();
        ss.close();
        
        
    }

}


【上传图片】

客户端:

public class UploadPicClient {

    /**
     * @param args
     * @throws IOException 
     * @throws UnknownHostException 
     */
    public static void main(String[] args) throws UnknownHostException, IOException {
        
        
        //1创建客户端socket
        Socket s = new Socket("192.168.1.100",10005);
        
        //2读取客户端要上传的图片文件
        FileInputStream fis= new FileInputStream("c:\\123.bmp");
        
        //3,
        OutputStream out= s.getOutputStream();
        byte[]buf =new byte[1024];
        int len=0;
        while((len=fis.read(buf))!=-1){
        out.write(buf,0,len);    
        }

        //告诉服务器,发送完毕,让服务端停止读取
        s.shutdownOutput();
        //读取服务端发回的内容
        InputStream in =s.getInputStream();
        byte[]bufIn=in.read(buf);
        int lenIn =in.read(buf);
        String text =new String(buf,0,lenIn);    
        System.out.println(text);
        fis.close();
        s.close();
    }

}

服务端:

public class UploadPicServer {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        
        //1创建TCP的socket服务端
        ServerSocket ss = new ServerSocket(10006);
        
        //2,获取客户端
        Socket s = ss.accept();
        
        System.out.println(s.getInetAddress().getHostAddress()+".....connected");
        
        //3,读取客户端发来的数据
        InputStream in= s.getInputStream();

        //将读取到数据存储到一个文件夹中。
        File dir = new File("c:\\pic");
        if (!dir.exists()){
            dir.mkdirs();
        }
        File file = new File(dir,ip+".bmp");
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buf =new byte[1024];
        int len=0;
         while((len=in.read(buf))!=-1){
            fos.write(buf,0,len);

            }

        //获取socket输出流,将上传成功字样发送给客户端

        OutputStream out  = s.getOutputStream();
        out.write("上传成功".getBytes());

        fos.close();
        s.close();        
        ss.close();
    }

}

现在这个样子的服务端只能接收处理一个客户端,因此需要修改

public class UploadPicServer {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
            
        //创建tcp的socket服务端。
        ServerSocket ss = new ServerSocket(10006);
        
        while(true){
            Socket s = ss.accept();            
            
            new Thread(new UploadTask(s)).start();        
            
        }
        //获取客户端。
        
        
//        ss.close();
        
        
    }

}

public class UploadTask implements Runnable {

    private static final int SIZE = 1024*1024*2;
    private Socket s;

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

    @Override
    public void run() {

        int count = 0;
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip + ".....connected");
        
        try{

        // 读取客户端发来的数据。
        InputStream in = s.getInputStream();

        // 将读取到数据存储到一个文件中。
        File dir = new File("c:\\pic");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file = new File(dir, ip + ".jpg");
        //如果文件已经存在于服务端 
        while(file.exists()){
            file = new File(dir,ip+"("+(++count)+").jpg");
        }
        
        
        FileOutputStream fos = new FileOutputStream(file);

        byte[] buf = new byte[1024];

        int len = 0;

        while ((len = in.read(buf)) != -1) {
            
            
            
            fos.write(buf, 0, len);
            
            if(file.length()>SIZE){
                System.out.println(ip+"文件体积过大");
                
                fos.close();
                s.close();
                
                
                System.out.println(ip+"...."+file.delete());
                
                return ;
            }
        }

        // 获取socket输出流,将上传成功字样发给客户端。
        OutputStream out = s.getOutputStream();
        out.write("上传成功".getBytes());

        fos.close();
        s.close();
        }catch(IOException e){
            
        }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值