廖雪峰Java13网络编程-1Socket编程-2TCP编程

1. Socket

在开发网络应用程序的时候,会遇到Socket这个概念。
Socket是一个抽象概念,一个应用程序经过一个Socket来创建一个远程链接,而Socket内部经过TCP/IP协议把数据传输到网络。

Socket/TCP/部分IP都是由操做系统提供的。不一样的编程语言只是提供了对操做系统调用的加单封装,例如Java提供的几个Socket相关的类就封装了操做系统提供的接口。
为何须要Socket?
由于仅仅经过IP地址进行通讯还不够,同一台计算机同一时间会运行多个网络程序。当计算机收到一个数据包的时候,只有IP地址是无法判断应该发送给哪一个应用程序的,因此操做系统抽象出Socket接口。每一个应用程序须要对应不一样的Socket,能够把Socket简单理解为IP地址+端口号。
端口号是操做系统分配的,是在0-65535之间的数字java

  • <1024是特权端口,须要管理员权限
  • >1024的端口能够由任意应用程序打开

2. Socket使用

Socket编程模型须要实现服务器端与客户端,由于2个应用程序通讯的时候不只须要对方的IP,还须要知道对方的端口号。因此服务器端必须先固定一个端口号,例如80。客户端在发起请求的时候,会直接请求80端口,同时告知本身的端口,这样双方就能够经过Socket进行通讯了。
客户端的编程:编程

Socket sock = new Socket(InetAddress,port);//链接到远程服务器的指定端口
    InputStream in = sock.getInputStream();//获取到输入和输出流
    OutputStream out = sock.getOutputStream();    
    //读写字节流

服务器端:缓存

ServerSocket ss = new ServerSocket(port); //监听指定端口号
    Socket sock = ss.accept();
    InputStream in = sock.getInputStream();
    OutputStream out = sock.getOutputStream();
    //读写字节流

TCPClient.java服务器

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class TCPClient {
    public static void main(String[] args) throws IOException{
        InetAddress addr = InetAddress.getLoopbackAddress(); //获取本机的InetAddress,一般是127.0.0.1
        try(Socket sock = new Socket(addr,9090)){ //打开远程链接
            try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(),StandardCharsets.UTF_8))){//BufferedReader类就是一个包装类,它能够包装字符流,将字符流放入缓存里,到缓存满了或者执行flush的时候,再读入内存,能够提交读的效率。
                try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8))){
                    writer.write("time\n");
                    writer.flush();//强制把缓存区的内容发送出去
                    String resp = reader.readLine();
                    System.out.println("Response:"+resp);
                }
            }
        }
    }
}

TCPServer.java网络

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.time.LocalTime;

public class TCPServer {
    public static void main(String[] args) throws Exception{
        ServerSocket ss = new ServerSocket(9090);
        System.out.println("TCP Server ready:");
        Socket sock = ss.accept();
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(),StandardCharsets.UTF_8))){
            try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8))){
                String cmd = reader.readLine(); //获取客户端传过来的数据
                if("time".equals(cmd)){
                    writer.write(LocalTime.now()+"\n");
                    writer.flush();
                }
            }
        }
        sock.close();
        ss.close();
    }
}

先运行服务器端,再运行客户端

socket

3. 总结:

TCP编程模型:编程语言

  • 客户端使用Socket(InetAddress,port)打开Socket
  • 服务器用ServerSocket监听端口
  • 服务器用accept接收链接并返回Socket
  • 双方经过Socket打开InputStream/OutputStream读写数据
  • flush()用于强制输出缓冲期
相关文章
相关标签/搜索