JAVA网络编程(TCP篇入门)

此次博客主要以代码为主,其中包含了丰富的注释

简单的tcp

简单介绍tcp是如何发送数据,以及接受数据

代码一:客户端

package com.net.tcp;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

/**
 * TCP协议发送数据的步骤
 * A:创建发送数据的socket对象。
 *  创建对象的时候要指定目标主机和端口
 * B:获取socket对象的输出流
 *  是字节流还是字符流?字节流。
 * C:写数据
 * D:释放资源
 * 
 * @author yuliyang
 * @version $Id: ClientDemo.java, v 0.1 2016年11月23日 下午10:57:55 yuliyang Exp $
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //A:创建发送数据的socket对象
        //Socket(InetAddress address, int port) 
        //Socket(String host, int port) 
        //java.net.ConnectException: Connection refused: connect
        //如果你先启动了客户端,发现如上错误,是因为服务端没有开启,TCP协议的程序,必须先开启服务器
        Socket s = new Socket("192.168.31.222", 10086);
        //B:获取socket对象的输出流
        OutputStream os = s.getOutputStream();
        //C:
        os.write("hello write".getBytes());
        //D:
        os.close();
        s.close();
    }
}

代码一:服务端

package com.net.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * TCP协议接收数据的步骤
 * A:创建接收数据的socket对象。
 *  创建对象的时候要指定端口
 * B:监听客户端连接,
 *      等待客户端连接
 * C:读数据,并显示在控制台
 * D:释放资源
 * 注意事项;服务器需要先开启
 * @author yuliyang
 * @version $Id: ClientDemo.java, v 0.1 2016年11月23日 下午10:57:55 yuliyang Exp $
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //A:ServerSocket(int port) 
        ServerSocket serverSocket = new ServerSocket(10086);
        //B:监听客户端连接
        // Socket accept()  侦听并接受到此套接字的连接。
        Socket s = serverSocket.accept();//此处为阻塞式方法
        //C:获取socket对象的输入流,并读取数据
        InputStream is = s.getInputStream();
        byte[] buf = new byte[1024];
        int len = is.read(buf);
        //此处为解析收到的数据
        String data = new String(buf, 0, len);
        System.out.println("data" + data);
        //D:释放资源
        is.close();
        serverSocket.close();
    }
}

如果上面的代码你看懂了的话,那就接着继续玩耍吧。

代码二:客户端,新增获取了服务端返回的信息

package com.net.tcp2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端socket
        Socket socket = new Socket("192.168.31.222", 12312);
        /**
         * 使用通道输出流写数据
         */
        OutputStream outputStream = socket.getOutputStream();

        outputStream.write("我是发送的".getBytes());
        /**
         * 使用通道输入流获取返回的消息
         */
        InputStream inputStream = socket.getInputStream();
        byte[] b = new byte[1024];
        int len = inputStream.read(b);
        String s = new String(b, 0, len);
        System.out.println("客户端获取到的响应是:" + s);
        socket.close();
    }
}

代码二:服务端

package com.net.tcp2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(12312);
        Socket s = serverSocket.accept();
        InputStream inputStream = s.getInputStream();
        byte[] buf = new byte[1024];
        int len = inputStream.read(buf);
        String data = new String(buf, 0, len);
        System.out.println("服务端获取到的数据是:" + data);
        /**
         * 使用通道返回响应,告诉客户端结果
         */
        OutputStream outputStream = s.getOutputStream();
        outputStream.write("我接收到了".getBytes());
        //释放资源
        serverSocket.close();
        inputStream.close();
        outputStream.close();
    }
}

代码三:客户端 新增需求:看注释

package com.net.tcp3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * 需求:把发送的数据改进为来自键盘录入,
 * 客户端发送数据用键盘录入,服务端把数据显示即可
 * 
 * @author yuliyang
 * @version $Id: ClientDemo.java, v 0.1 2016年11月24日 下午9:08:14 yuliyang Exp $
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket("192.168.31.222", 10010);
        //读取键盘录入的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //封装:将通道内的输出字节流转化为字符流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        s.close();
    }
}

代码三:服务端

package com.net.tcp3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(10010);
        Socket s = serverSocket.accept();
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println("接收的数据为:" + line);
        }
        //释放资源
        s.close();
        serverSocket.close();
    }
}

代码四:客户端

需求:服务端需要将从客户端获取的资源写入到文件中

package com.net.tcp5;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("192.168.31.222", 10086);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        socket.close();
    }
}

代码四:服务端

package com.net.tcp5;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器socket对象
        ServerSocket serverSocket = new ServerSocket(10086);
        //监听客户端连接
        Socket socket = serverSocket.accept();//阻塞式
        //封装通道内的输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //将数据写入到文件中
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\a.txt"));
        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        bw.close();
        serverSocket.close();
    }
}

代码五:客户端

需求:客户端读取本地文件,并传送给服务端,服务端收到文件之后,并copy一份

package com.net.tcp6;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的对象
        Socket s = new Socket("192.168.31.222", 10086);
        //读取文件的数据
        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();
        }
        s.close();
        br.close();
    }
}

代码五:服务端

package com.net.tcp6;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器对象
        ServerSocket serverSocket = new ServerSocket(10086);
        //监听客户端连接
        Socket s = serverSocket.accept();
        //把通道内的输入流封装一下
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        //把输入流输出到文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.txt"));
        String line = null;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        serverSocket.close();
        bw.close();

    }
}

代码六:客户端

需求:在文件接收完成之后,服务器需要通知客户端,文件接收完成
问题:会因为阻塞式,导致接收不到反馈消息
解决方案:A:自定义结束标签
B:使用socket自带的方法
此处只展现socket自带方案

package com.net.tcp7;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * 我把文件发给你了,你没有告诉我文件你是否收到文件
 * 需要服务端给我一个反馈
 * 
 * @author yuliyang
 * @version $Id: ClientDemo.java, v 0.1 2016年11月24日 下午10:21:16 yuliyang Exp $
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的对象
        Socket s = new Socket("192.168.31.222", 10086);
        //读取文件的数据
        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提供了一个方法:
         *  shutdownOutput
         * 禁用输出流  方法
         */
        s.shutdownOutput();
        BufferedReader infoByServer = new BufferedReader(new InputStreamReader(s.getInputStream()));

        String data = infoByServer.readLine();//阻塞式
        System.out.println("client" + data);
        s.close();
        br.close();
    }
}

代码六:服务端

package com.net.tcp7;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 收到文件之后,给客户端一个反馈
 * 
 * @author yuliyang
 * @version $Id: ServerDemo.java, v 0.1 2016年11月24日 下午10:22:00 yuliyang Exp $
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器对象
        ServerSocket serverSocket = new ServerSocket(10086);
        //监听客户端连接
        Socket s = serverSocket.accept();
        //把通道内的输入流封装一下
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        //把输入流输出到文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.txt"));
        String line = null;
        while ((line = br.readLine()) != null) {//阻塞式
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        /**
         * 新增反馈
         * 从通道将反馈返回回去
         */
        BufferedWriter feadback = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        feadback.write("数据接收成功了");
        feadback.newLine();
        feadback.flush();
        serverSocket.close();
        bw.close();

    }
}

希望看到我的文章的人可以多给反馈,thanks

猜你喜欢

转载自blog.csdn.net/yly20150203/article/details/53327232