Java网络编程

什么是网络编程呢?

它的目的是我们直接或者间接的通过网络协议于其他计算机进行通讯。网络编程中有两个主要的问题,一个是如何准确的定位网络上一台或多主机,另一个就是找到主机以后如何高效的进行数据传输。

在TCP/IP协议里面,IP层主要负责主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。而TCP层则提供面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。

大家常说的C/S结构,就是客户机/服务器结构,即使通信双方一方作为服务器等待客户提出请求并予以响应。客户则在需要服务时向服务器提出申请。服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。

ping一下常见的几个搜索引擎

Google(不是因为我没有科*上网嗷,是Google不让我ping的,Ping不通不代表就是无法访问网页。Ping用的是ICMP协议,我们一般代理都是http,而且有的网站的防火墙也不允许ping,所以ping不通Google这些站其实很正常。)

1563242260842.png

Bing

1563242298593.png

Baidu

1563242307488.png

我自己的服务器

1563242315264.png

(百度延迟还是还是低呀)

TCP/IP简介

TCP/IP协议族有IP协议,TCP协议,UDP协议。现在主要的socket类型是流套接字(TCP)数据报套接字(UDP):

  1. TCP协议(Tranfer Control Protocol)提供了面向连接的服务,通过它建立的是可靠连接,保证可靠传输。通过TCP得到的是一个完整的顺序的数据

  2. UDP协议(User Datagram Protocol)是无连接的服务,每个数据包是一个独立的信息,包含完整的源码和目的地址,但是它没办法到达的顺序和内容的正确性。

我们都知道,想要得到一些东西就要损失另一些东西,TCP似乎很美好,建立连接可以传输大数据,那为什么我们还要使用UDP呢。可靠性是要付出时间作为牺牲的,在TCP的过程中,我们需要对它进行一些维护和正确内容的检测,这就导致了它的效率不会特别高。

从url获取网络资源
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class URLReader {
    public static void main(String[] args) throws IOException {
        URL url = null;
        try {
            url = new URL("http://www.cnblogs.com/quixotey/");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        String inputLine = in.readLine();

        while (inputLine != null) {
            System.out.println(inputLine);
        }
        in.close();
      }
    }


urlConnection
URLConnection urlConnection = url.openConnection();
        urlConnection.setDoOutput(true);
//输出流
        PrintStream printStream = new PrintStream(urlConnection.getOutputStream());
//输入流
        DataInputStream dataInputStream = new DataInputStream(urlConnection.getInputStream());
        //如果要写的话,不可以先输入流再输出流
        String line = dataInputStream.readLine();
        printStream.println("Client...");

Demo 模拟服务端和客户端通信

客户端:Client 1,Client 2代码相同

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.SocketTimeoutException;

public class Client2 {
    public static void main(String[] args) throws IOException {
        //connection in 20006 port use TCP
        Socket socket = new Socket("127.0.0.1",20006);
        socket.setSoTimeout(10000);
        //获取键盘输入
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        //获取输出流,发送到服务端
        PrintStream out = new PrintStream(socket.getOutputStream());
        // 获取Socket的输入流,用来接收从服务端发送过来的数据
        BufferedReader buf = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        boolean flag = true;
        while (flag) {
            System.out.print("Input:");
            String str = input.readLine();
            // 发送数据到服务端
            out.println(str);
            if ("bye".equals(str)) {
                flag = false;
            } else {
                try {
                    // 从服务器端接收数据有个时间限制(系统自设,也可以自己设置client.setSoTimeout(10000);),超过了这个时间,便会抛出该异常
                    String echo = buf.readLine();
                    System.out.println(echo);
                } catch (SocketTimeoutException e) {
                    System.out.println("Time out, No response");
                }
            }
        }
        input.close();
        if (socket != null) {
            // 如果构造函数建立起了连接,则关闭套接字,如果没有建立起连接,自然不用关闭
            socket.close(); // 只关闭socket,其关联的输入输出流也会被关闭
        }


    }
}

Server

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

public class Server {
    public static void main(String[] args) throws IOException {
        //服务器在端口上面监听用户的TCP连接
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(20006);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("start server");
        Socket socket = null;
        boolean f = true;
        while(f){
            socket = serverSocket.accept();
            System.out.println("Connection successfully");

            new Thread(new ServerThread(socket)).start();
        }
    }
}

ServerThread

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

public class ServerThread implements Runnable{
    private Socket socket = null;

    public  ServerThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        //获取socket的输出流,用来向客户端发送数据、
        try {
            PrintStream out = new PrintStream(socket.getOutputStream());
            //获取输入流,用来接收客户端发送过来的数据
            BufferedReader buf = new BufferedReader(new InputStreamReader(socket.getInputStream()));

//            PrintStream in =  new PrintStream(String.valueOf((socket.getInputStream())));
            boolean flag = true;
            while(flag){
                String str = buf.readLine();
                if ("bye".equals(str)){
                    flag = false;
                }else {
                    out.println("Reply :"+str);
                }
            }
            out.close();
            socket.close();
            System.out.println("Close");
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

运行结果

net1.png
net2.png
net3.png

参考


Java网络编程:TCP的socket编程

Java网络编程

posted @ 2019-07-16 17:03  天天不是小可爱  阅读(202)  评论(0编辑  收藏  举报