网络编程。

TCP通信:

TCP通信是面向连接的通信,客户端和服务器端必须三次握手,建立逻辑连接。

通信步骤:客户端请求服务器,建立连接,这个连接中包含一个IO(字节流)对象,用该对象进行通                               信。服务器没有IO流,用客户端提供的IO流和客户端交互。

Java中,提供两个类用于实现TCP通信程序:

  客户端: java.net.Socket    服务端:java.net.ServerSocket.

Socket:

  构造方法:Socket(String host,int port) 创建一个流套接字并连接到指定主机的指定端口号

  参数:String host:服务器名称/IP    int port :端口号。

  成员方法:OutputStream getOutputStream(), 返回此套接字的输出流。

       InputStream getInputStream(),........................输入流。

  实现步骤:1,创建Socket对象 。

       2,用getOutputStream()获取网络字节输出流OutputStream对象。

       3,用OutputStream对象的 write方法,给服务器发送数据。

       4,用getInputStream() 获取 网络字节输入流InputStream对象。      

       5,用read方法,读取服务器返回的数据。

       6,释放资源。

  注意:1,客户端和服务器进行交互,必须使用Socket提供的网络流。

     2,创建Socket对象的时候,就会和服务器三次握手建立连接,如果服务器没启动,会                           抛出异常。

 public static void main(String[] args) throws IOException{
        Socket socket=new Socket("127.0.0.1",8888);
        OutputStream os= socket.getOutputStream();
        os.write("hello server".getBytes());
        InputStream is=socket.getInputStream();
        byte[] bytes=new byte[1024];
        int len=is.read(bytes);
        System.out.println(new String(bytes,0,len));
        os.close();
    }

ServerSocket:

  构造方法:   ServerSocket(int port) 创建绑定到特定端口的服务器套接字。

  成员方法:Socket accept(),获取客户端的Socket对象。

 public static void main(String[] args) throws IOException{
        ServerSocket serverSocket=new ServerSocket(8888);
        Socket socket=serverSocket.accept();
        InputStream is=socket.getInputStream();
        byte[] bytes=new byte[1024];
        int len=is.read(bytes);
        System.out.println(new String(bytes,0,len));
        OutputStream os=socket.getOutputStream();
        os.write("received".getBytes());
        serverSocket.close();
        socket.close();
    }

 文件上传案例:

总过程:客户端读取本地文件,上传到服务器,服务器把文件保存并反馈信息。

客户端代码:

public class Client {
    public static void main(String[] args) throws IOException{
        File file=new File("C:\Users\天\Desktop\1.jpg");
        FileInputStream fis=new FileInputStream(file);
        Socket socket=new Socket("127.0.0.1",8888);
        OutputStream os=socket.getOutputStream();
        int len=0;
        byte[] bytes=new byte[1024];
        while ((len=fis.read(bytes))!=-1){
            os.write(bytes,0,len);
        }
        InputStream is = socket.getInputStream();
        System.out.println(String.valueOf(is.read(bytes)));
        os.close();
        fis.close();
        socket.close();
    }
}

服务器代码:

public class Server {
    public static void main(String[] args) throws IOException{
        File file=new File("C:\Users\天\Desktop\2.jpg");
       ServerSocket serverSocket=new ServerSocket(8888);
       Socket socket=serverSocket.accept();
        InputStream is = socket.getInputStream();
        FileOutputStream fos=new FileOutputStream(file);
        int len=0;
        byte[] bytes =new byte[1024];
        while ((len=is.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        socket.getOutputStream().write("上传成功".getBytes());
        fos.close();
        socket.close();
        serverSocket.close();
    }
}

出现问题:程序运行过程时,文件成功复制,但是程序并不会结束。

原因:客户端不会把结束标记写给服务器,服务器的read()读不到结束标记,会进入阻塞状态。

解决:给服务器写一个结束标记。

void shutdownOutput() : 禁用此套接字的输出流,后跟TCP的正常连接终止序列。

原文地址:https://www.cnblogs.com/zhangyuhao/p/10877858.html