我们在日常上网时,会经常登录某个网址,发送我们的请求信息,然后从该网站得到我们想要的信息。这个是怎么实现的呢。其实,我们可以把我们自己当成客户端,网站当成服务端。其实这是个相对的概念,就是谁收到请求,谁就是服务端;谁发送请求,谁就是客户端。而发送和接收请求都是基于Socket 对象实现的。而这个过程是怎么样的呢?(这里介绍的是基于TCP/IP 的通信)
下面我先用一个简单的图解表示一下:

通过上面的图解,我们可以很清晰的看到整个通信的流程。
对于编码来实现的话,我们首先需要编写服务端,然后再编写客户端。

服务端的实现思路:

  1. 首先创建ServerSocket类的对象,并定义端口
  2. 然后利用该对象的accept() 的方法,来等待接收请求,注意这里是阻塞的状态。
  3. 如果接收到请求,就会相应的创建Socket类的对象
  4. 首先我们可以向客户端发送消息,“我们收到了你的请求!”,利用Socket对象的输出流。
  5. 我们利用Scoket对象获取输入流,接收客户端发送的信息。
  6. 关闭相关资源

客户端的实现思路:

  1. 创建客户端的Socket对象,并指定想要连接的服务端的IP地址和端口号
  2. 获取Socket对象的输入流,接收服务端发送的消息
  3. 获取Socket对象的输出流,向服务端发送指定的内容
  4. 关闭相关资源

几个需要知道的概念:

  • IP地址:为实现网络中不同计算机之间的通信,每台机器必须有一个唯一的标识–IP地址
    常见格式:192.168.25.130,本机地址一般为127.0.0.1或者“localhost”
  • 端口号:为了区分不同应用的程序,范围为0~65535, 其中 0-1023 为系统保留,我们要定义最好大于1023.
  • 传输的数据单位:输入和输出流的传输的最小单位是字节,8个bit。
  • TCP:Transmission Control Protocol 传输控制协议
  • IP:Internet Protocol 互联网协议

具体的代码实现:
首先是服务端:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;/*** @author:Xiao* @Date:2021/5/31**/
public class Server {public static void main(String[] args) {try {//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口ServerSocket serverSocket = new ServerSocket(8888);System.out.println("***服务器即将启动,等待客户端的连接***");//2.调用accept()方法开始监听,等待客户端的连接Socket socket=serverSocket.accept();System.out.println("连接一台客户机");//3.获取输入流,并读取客户端信息InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);// 使用字符缓冲流BufferedReader br = new BufferedReader(isr);String info=null;while((info=br.readLine())!=null){//循环读取客户端的信息。一行一行的读取System.out.println("我是服务器,客户端说:"+info);}socket.shutdownInput();//关闭输入流//4.获取输出流,响应客户端的请求OutputStream os = socket.getOutputStream();// 使用标准打印流PrintWriter pw = new PrintWriter(os);pw.write("欢迎您!");pw.flush();//调用flush()方法将缓冲输出socket.shutdownOutput();// 5.关闭资源br.close();is.close();isr.close();os.close();pw.close();socket.close();serverSocket.close();}catch (IOException e){e.printStackTrace();}}
}

客户端的是代码实现:

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;/*** @author:Xiao* @Date:2021/5/31**/
public class Client {public static void main(String[] args) {try {//1.创建客户端Socket,指定服务器地址和端口Socket socket=new Socket("localhost", 8888);//2.获取输出流,向服务器端发送信息OutputStream os=socket.getOutputStream();//字节输出流PrintWriter pw=new PrintWriter(os);//将输出流包装为打印流pw.write("用户名:alice;密码:789");pw.flush();socket.shutdownOutput();//关闭输出流//3.获取输入流,并读取服务器端的响应信息InputStream is=socket.getInputStream();BufferedReader br=new BufferedReader(new InputStreamReader(is));String info=null;while((info=br.readLine())!=null){System.out.println("我是客户端,服务器说:"+info);}socket.shutdownInput();//4.关闭资源br.close();is.close();pw.close();os.close();socket.close();}  catch (IOException e) {e.printStackTrace();}}
}

输出片段:

服务端的窗口:
***服务器即将启动,等待客户端的连接***
连接一台客户机
我是服务器,客户端说:用户名:alice;密码:789客户端的窗口:
我是客户端,服务器说:欢迎您!

考虑的问题:当我们需要用多个客户端连通服务器的时候应该怎么办呢?

其实我们可以采用多线程的方式。我们可以把服务端每接收到一个连接时,就启动一个线程对象,然后去执行相应的任务。我们可以把这个代码块可以写成Thread类。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;/** 服务器线程处理类*/
public class ServerThread extends Thread {// 和本线程相关的SocketSocket socket = null;public ServerThread(Socket socket) {this.socket = socket;}//线程执行的操作,响应客户端的请求public void run(){InputStream is=null;InputStreamReader isr=null;BufferedReader br=null;OutputStream os=null;PrintWriter pw=null;try {//获取输入流,并读取客户端信息is = socket.getInputStream();isr = new InputStreamReader(is);br = new BufferedReader(isr);String info=null;while((info=br.readLine())!=null){//循环读取客户端的信息System.out.println("我是服务器,客户端说:"+info);}socket.shutdownInput();//关闭输入流//获取输出流,响应客户端的请求os = socket.getOutputStream();pw = new PrintWriter(os);pw.write("欢迎您!");pw.flush();//调用flush()方法将缓冲输出} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{//关闭资源try {if(pw!=null)pw.close();if(os!=null)os.close();if(br!=null)br.close();if(isr!=null)isr.close();if(is!=null)is.close();if(socket!=null)socket.close();} catch (IOException e) {e.printStackTrace();}}}
}

然后在服务端的accept() 的方法下改成while循环,不断的接收新连接的客户端。则代码可以相应的改成:(因为在socket=serverSocket.accept(); 等待连接的时候是阻塞的状态,所以不会一直无限循环下去,导致资源的浪费。)

/** 基于TCP协议的Socket通信* 服务器端,多线程实现*/
public class Server {public static void main(String[] args) {try {//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口ServerSocket serverSocket=new ServerSocket(8888);Socket socket=null;//记录客户端的数量int count=0;System.out.println("***服务器即将启动,等待客户端的连接***");//循环监听等待客户端的连接while(true){//调用accept()方法开始监听,等待客户端的连接socket=serverSocket.accept();//创建一个新的线程ServerThread serverThread=new ServerThread(socket);//启动线程serverThread.start();count++;//统计客户端的数量System.out.println("客户端的数量:"+count);InetAddress address=socket.getInetAddress();System.out.println("当前客户端的IP:"+address.getHostAddress());}} catch (IOException e) {e.printStackTrace();}}
}

Socket通信原理(多线程)相关推荐

  1. Socket 通信原理

    整理和总结了一下大家常遇到的问题: 1. 客户端socket发送消息后,为什么服务端socket没有收到?2. 使用while 循环实现连续输入,是不是就是多线程模式?3. 对多线程处理机制不是很明白 ...

  2. Java——Socket通信原理

    * Socket通信原理图解* A:Socket(中文翻译为:电源插座)套接字概述* 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识套接字* 通信的两端都有Socket(两端都 ...

  3. Socket通信学习(一):Socket通信原理

    Socket通信学习(一):Socket通信原理 HoloLens的开发最近需要用到Socket通信,所以创建本系列进行记录,欢迎大家批评指正! 前言 应用Socket进行设备通信,首先需要了解Soc ...

  4. Socket 通信原理(Android客户端和服务器以TCPUDP方式互通)

     ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当,还望指教. 一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是So ...

  5. socket通信原理简介

    Socket原理,大致分为以下几个步骤. 服务器端的步骤如下: (1)首先,在实用Socket之前,要首先初始化Socket,就是实用AfxSocketInit()函数. (2)在初始化完成以后,就可 ...

  6. TCP及socket通信原理详解

    TCP/IP原型 DARPA一个项目,逐渐演变而来的. 端口号 0~1023:管理员才有权限使用,永久地分配给某应用使用: 注册端口: 1024~41951:只有一部分被注册,分配原则上非特别严格: ...

  7. AF_INET域与AF_UNIX域socket通信原理对比

    1. AF_INET域socket通信过程 典型的TCP/IP四层模型的通信过程. 发送方.接收方依赖IP:Port来标识,即将本地的socket绑定到对应的IP端口上,发送数据时,指定对方的IP端口 ...

  8. python通信原理实验报告_【Python之旅】第五篇(一):Python Socket通信原理-阿里云开发者社区...

    只要和网络服务涉及的,就离不开Socket以及Socket编程,下面就说说Python Socket通信的基本原理. 1.Socket socket也称作"套接字",用于描述IP地 ...

  9. Socket通信原理

    对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1.         什么是TCP/IP.UDP? 2.         Soc ...

最新文章

  1. 2022-2028年中国铁路信息化建设投资分析及前景预测报告
  2. 车载以太网之权威指南_awk权威指南之 终结篇!
  3. NCEPU:线下组队学习周报(011)
  4. 由点到面(面试经验)
  5. MySQL中的用户管理
  6. Buuctf(pwn) jarvisoj_tell_me_something 栈溢出
  7. 推荐ApacheCN开源的一个机器学习路线图
  8. 为什么 JavaScript 的 this 要这么用?
  9. 深入理解Spark 2.1 Core (一):RDD的原理与源码分析
  10. leetcode349. 两个数组的交集(思路+详解)
  11. 怎样设计访谈提纲_服务设计简史
  12. 梦想与现实之间的距离
  13. 8位模型计算机设计与仿真
  14. JS - 笛卡尔积算法
  15. 高校计算机房设计过程,高校计算机房建设中的一些注意事项.pdf
  16. java环境一键_Java环境变量一键配置
  17. 导入技能要素三大类_财务管理类专业(技能)课程体系
  18. dockerfile编写之恋爱初体验~~~
  19. 自学Java半年,没有包装简历,成功找到工作!!个人经验分享
  20. 恢复win10 Windows照片查看器

热门文章

  1. 【用户增长模型-上篇】从AARRR模型到RARRA模型,互联网到底经历了什么?
  2. 人类的第一语言是什么
  3. 华为手机用户专享福利,64套精美手机主题
  4. ddl/dml/dql/dcl
  5. ARP欺骗原理及实验
  6. CK+人脸表情数据库地址
  7. HTML表单控件之特殊控件
  8. java简单实现计算器功能
  9. Failed to launch emulator 和 Failed to install the app解决方法
  10. 大家注意到QQ迷你新闻中的一项技术了吗?