1. Socket

在开发网络应用程序的时候,会遇到Socket这个概念。

Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据传输到网络。



Socket/TCP/部分IP都是由操作系统提供的。不同的编程语言只是提供了对操作系统调用的加单封装,例如Java提供的几个Socket相关的类就封装了操作系统提供的接口。

为什么需要Socket?

因为仅仅通过IP地址进行通信还不够,同一台计算机同一时间会运行多个网络程序。当计算机收到一个数据包的时候,只有IP地址是没法判断应该发送给哪个应用程序的,所以操作系统抽象出Socket接口。每个应用程序需要对应不同的Socket,可以把Socket简单理解为IP地址+端口号。

端口号是操作系统分配的,是在0-65535之间的数字

  • <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();
}
}

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



3. 总结:

TCP编程模型:

  • 客户端使用Socket(InetAddress,port)打开Socket
  • 服务器用ServerSocket监听端口
  • 服务器用accept接收连接并返回Socket
  • 双方通过Socket打开InputStream/OutputStream读写数据
  • flush()用于强制输出缓冲期

廖雪峰Java13网络编程-1Socket编程-2TCP编程的更多相关文章

  1. 廖雪峰Java13网络编程-1Socket编程-5UDP编程

    1. UDP编程: 不需要建立连接 可以直接发送和接收数据 1.1 客户端 DatagramSocket sock = new DatagramSocket(){} sock.connect(addr ...

  2. 廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程

    TCP多线程编程 一个ServerSocket可以和多个客户端同时建立连接,所以一个Server可以同时与多个客户端建立好的Socket进行双向通信. 因此服务器端,当我们打开一个Socket以后,通 ...

  3. 廖雪峰Java13网络编程-1Socket编程-1网络编程概念

    1.计算机网络 1.1 什么是计算机网络? 两台或更多计算机组成的网络 同一网络内的任意2台计算机都可以直接通信 所有计算机必须遵循同一种网络协议 1.2 什么是互联网 互联网是网络的网络 互联网采用 ...

  4. 廖雪峰Java13网络编程-3其他-2RMI远程调用

    1.RMI远程调用: Remote Method Invocation 目的:把一个接口方法暴露给远程 示例: 定义一个接口Clock,它有一个方法能够获取当前的时间,并编写一个实现类,来实现这个接口 ...

  5. 廖雪峰Java13网络编程-3其他-1HTTP编程

    1.HTTP协议: Hyper Text Transfer Protocol:超文本传输协议 基于TCP协议之上的请求/响应协议 目前使用最广泛的高级协议 * 使用浏览器浏览网页和服务器交互使用的就是 ...

  6. 廖雪峰Java13网络编程-2Email编程-2接收Email

    1接收Email协议类型 接收Email:收件人通过MUA软件把邮件从MDA抓取到本地计算机的过程. 1.1 POP3 从MUA到MDA使用最广泛的是协议是POP3 Post Office Proto ...

  7. 廖雪峰Java13网络编程-2Email编程-1发送email

    1.邮件发送 1.1传统邮件发送: 传统的邮件是通过邮局投递,从一个邮局到另一个邮局,最终到达用户的邮箱. 1.2电子邮件发送: 与传统邮件类似,它是从用户电脑的邮件软件(如outlook)发送到邮件 ...

  8. 廖雪峰Java1-3流程控制-9break、continue

    break跳出循环 int sum=0; for(int i=1; ;i++) { sum =sum + i; if(i == 100) { break; } } System.out.println ...

  9. 廖雪峰Java1-3流程控制-6 do-while循环

    do-while循环 do-while先执行循环,再判断条件. 条件满足时继续循环:条件不满足时退出:至少循环1次 int sum =0; int n = 1; do{ sum = sum + n; ...

随机推荐

  1. 深入理解java虚拟机JVM(下)

    深入理解java虚拟机JVM(下) 链接:https://pan.baidu.com/s/1c6pZjLeMQqc9t-OXvUM66w 提取码:uwak 复制这段内容后打开百度网盘手机App,操作更 ...

  2. soapui基础知识

    一.基础知识 1.测试步骤(teststep)为最小单位,一个完整的测试用例由多个测试步骤组成: 2.一个测试用例(testcase)代表一个完整的操作 3.测试集(testsuite)主要是为了区分 ...

  3. linux 重启mysql redis等服务器

    redis重启 如果是用apt-get或者yum install安装的redis, 可以直接通过下面的命令停止/启动/重启 /etc/init.d/redis-server stop /etc/ini ...

  4. Go: Println 与 Printf 的区别

    Go 学习笔记:Println 与 Printf 的区别,以及 Printf 的详细用法 2017-12-19 15:39:05 zgh0711 阅读数 26255更多 分类专栏: Go   版权声明 ...

  5. k8s集群搭建之二:etcd集群的搭建

    一 介绍 Etcd是一个高可用的 Key/Value 存储系统,主要用于分享配置和服务发现. 简单:支持 curl 方式的用户 API (HTTP+JSON) 安全:可选 SSL 客户端证书认证 快速 ...

  6. 最大流EK和Dinic算法

    最大流EK和Dinic算法 EK算法 最朴素的求最大流的算法. 做法:不停的寻找增广路,直到找不到为止 代码如下: @Frosero #include <cstdio> #include ...

  7. 2-Harris角点检测

    1. 何为角点? 下面有两幅不同视角的图像,通过找出对应的角点进行匹配. 再看下图所示,放大图像的两处角点区域: 我们可以直观的概括下角点所具有的特征: >轮廓之间的交点: >对于同一场景 ...

  8. (转)浅谈C中的malloc和free

    原帖及讨论:http://bbs.bccn.net/thread-82212-1-1.html 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的malloc()和free()两个函数 ...

  9. (转)MySQL安装及配置指南

    转:http://wiki.ubuntu.org.cn/MySQL%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97 安装MySQL sudo apt-get install m ...

  10. 您应升级到 MySQL 5.5.0 或更高版本。 phpmyadmin

    最近又折腾LAMP了.从官方下载的phpmyadmin在部署的时候发现 “您应升级到 MySQL 5.5.0 或更高版本”.原因是我安装的mysql数据库版本过低. 解决思路: 1.升级mysql版本 ...