使用Socket进行通信,需要有客户机和服务器。客户机和服务器可以在同一台机器上,但客户机和服务器处理的信息及信息处理方式是不同的,可以分为客户机程序和服务器程序。本实例介绍实现点对点通信,即一个服务器端监听一个客户端的请求的通信。
实现点对点通信的技术要点如下:
Socket通常作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过Socket向网络发出请求或者应答网络请求。Socket是在建立网络连接时使用。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。
对于一个网络连接来说,socket是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。
Socket服务器端需要在某个端口上开启服务器端类型的类: java.net.ServerSocket。通过accept()方法用于产生"阻塞",直到接收到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
Socket客户端根据服务器端的IP地址和端口号创建一个Socket对象,连接服务器。
服务器端持有ServerSocket对象,客户端持有Socket对象,服务器端的ServerSocket对象从服务器端指向客户端,而客户端的Socket对象从客户端指向服务器端,就像在服务器端和客户端建立了两条单向的管道。
服务器端程序
package core;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;class SocketServer {// Socket服务器端private int port; // 端口号public SocketServer(int port) {this.port = port;start();}private void start() {// 启动服务器端的方法try {ServerSocket serverSocket = new ServerSocket(port);// 根据端口创建服务器System.out.println("服务器已启动,监听端口号为:" + port);System.out.println("正在等待客户端连接。。。。。");Socket socketAccept = serverSocket.accept();// 挂起等待客户的请求BufferedReader in = new BufferedReader(new InputStreamReader(socketAccept.getInputStream()));// 获得(读取客户端的数据流)PrintWriter out = new PrintWriter(socketAccept.getOutputStream(), true); // 获得写往客户端的(数据输出流),true表示自动刷新out.println("服务器端连接成功。。。。");out.println("输入exit断开与服务器的连接");boolean done = false;while (!done) {String line = in.readLine();// 读取客户端每行的内容//System.out.println("line : "+line);if (line == null)done = true;else {System.out.println("客户端传来的内容: " + line);String message = infoUpperCase(line);// 变成大写再传回客户端去out.println("从服务器端口发送的内容 "+message); //--该处的print要加ln,否则就会无法往客户端传递消息if (line.trim().equals("exit")) // 退出判断done = true;}}socketAccept.close();  //关闭通信资源} catch (IOException e) {System.out.println("启动服务器端出现错误:"+e.getMessage());}}public String infoUpperCase(String line) {return line.toUpperCase(); // 将字符串大写}
}public class TextSocketServer {public static void main(String[] args) {try {SocketServer server=new SocketServer(8080);} catch (Exception e) {System.out.println("测试服务器端监听出错: "+e.getMessage());}}
}

客户端程序

package core;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;class Client { // Socket客户端private String host; // IP地址private int port; // 端口号public Client(String host, int port) {this.host = host;this.port = port;connectSocket();// 调用连接方法}public void connectSocket() {Socket socketConn; // 声明客户端的Socket连接try {if (host.equals("localhost") || host.equals("127.0.0.1")) {// 判断IP地址(域名)如果是本机localhostsocketConn = new Socket(InetAddress.getLocalHost(), port);// 创建本地Socket连接//如果该方法InetAddress.getLocalHost()报错,则要在sudo vi /private/etc/hosts 中添加本机地址与你主机名的映射,类似  127.0.0.1 主机名//然后终端执行命令 dscacheutil -flushcache,之后主机地址便可正常解析} else {socketConn = new Socket(InetAddress.getByName(host), port);// 创建远程socket连接}BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));// 获得从键盘输入的流PrintWriter out = new PrintWriter(socketConn.getOutputStream(), true);// 往服务器写内容的数据流// 从服务器获得信息BufferedReader in = new BufferedReader(new InputStreamReader(socketConn.getInputStream()));// 接收服务器发送内容的输入流System.out.println("服务器信息:" + in.readLine());System.out.println("服务器信息:" + in.readLine());System.out.println("请输入>");boolean done = false;while (!done) {String line = stdin.readLine();// 获得从键盘输入的每行字符out.println(line);// 发送到服务器端  --该处的print要加ln,否则就会无法往服务器端传递消息if (line.equalsIgnoreCase("exit")) // 读到exit则结束循环done = true;String info = in.readLine(); // 从服务器读取字符串System.out.println("服务器信息:" + info);// 显示从服务器发送来的数据if (!done)System.out.println("请输入>");}socketConn.close(); // 关闭资源} catch (SecurityException e) {System.out.println("连接服务器出现安全问题!"+e.getMessage());} catch (IOException e) {System.out.println("连接服务器出现I/O问题!"+e.getMessage());}}
}public class TextSocketClient {// Socket客户端类public static void main(String[] args) {try {new Client("localhost", 8080); // IP地址为本机,端口为8080} catch (Exception e) {System.out.println("测试客户端连接出错:" + e.getMessage());}}
}

客户端程序运行截图


服务器端程序运行截图
源程序解读
(1)SocketServer类构造方法传入端口参数和调用本类的start()方法来启动服务器端监听客户端的信息。
(2)start()方法创建服务器端的ServerSocket对象,服务器端ServerSocket对象的accept()方法创建客户端的Socket对象,挂起等待客户端的请求。根据getInputStream()方法获取客户端的数据输入流创建缓冲对象。根据getOutputStream()方法获得写完客户端的数据输出流。运用标识为真条件循环,根据缓冲对象的readLine()方法读取客户端每行内容,将读取的内容经过大写处理后输出到客户端,如果传来的数据是exit则设标识为假,退出循环。最后释放有关的通信资源。
(3)Client类的构造方法初始主机和端口并调用connectSocket()方法来调用相关主机连接和获得服务器端信息。
(4)connetSocket()方法判断传入的主机,如果是本机则创建本地Socket对象,否则创建远程Socket连接对象。根据封装从键盘输入的流创建缓冲读对象,根据getOutputStream()方法获得服务器端写内容的数据流创建写数据流。运用标识为条件循环读取键盘输入的每行字符,如果读取的数据为exit则退出循环。缓冲读对象的readLine()方法获得从服务器端读取的信息。
(5)我在调试代码时遇到两个问题。问题1:创建本地Socket连接时,方法InetAddress.getLocalHost()报错
socketConn = new Socket(InetAddress.getLocalHost(), port);// 创建本地Socket连接
这是因为InetAddress.getLocalHost()要去/private/etc/hosts地址查找你主机名和IP地址的映射关系,它没有找到就报错了。
解决办法:
1.在sudo vi /private/etc/hosts 中添加本机地址与你主机名的映射,类似 127.0.0.1 主机名
2. 在终端执行命令 dscacheutil -flushcache,之后主机地址便可正常解析
问题2:在控制台输入字符串后,按回车没有反应
原因:stdin.readLine()方法从键盘输入的每行字符后,out获得输出流,但是它的print方法必须加ln,否则就会无法往服务器端传递消息
解决办法
                                String line = stdin.readLine();// 获得从键盘输入的每行字符out.println(line);// 发送到服务器端  --该处的print要加ln,否则就会无法往服务器端传递消息

Java网络编程笔记(三):点对点通信(Socket基于TCP协议)相关推荐

  1. {网络编程}和{多线程}应用:基于TCP协议【实现多个客户端发送文件给一个服务器端】--练习

    要求: 实现多个客户端发送文件给一个服务器端提示:多个人创建客户端发送文件,服务端循环接收socket,从socket中获取文件 说明:这里我们只要建立一个服务端就可以了,然后让多台电脑使用客户端给这 ...

  2. Java网络编程笔记5

    在Java网络编程笔记4中我们看到了客户端与服务器通信的过程,只是在前面的程序只是单个客户端与服务器通信 的例子. 接下来我们看如何实现多个客户端与服务器通信,对于服务器来说,它要为每个客户端请求的S ...

  3. java网络编程的三要素

    1.IP地址,是设备的标识.Java学习笔记http://www.mobiletrain.org/note/java/ 要想让网络中的计算机能相互通信,必须为每台计算机指定一个标识号,通过此标识号来指 ...

  4. 网络编程知识预备(3) ——SOCKET、TCP、HTTP之间的区别与联系

    参考:SOCKET,TCP,HTTP之间的区别与联系 作者:丶PURSUING 发布时间: 2021-03-19 11:54:01 网址:https://blog.csdn.net/weixin_44 ...

  5. Java网络编程笔记

    Java网络编程 14-1 网络编程概述 14-2 网络通信要素概述 14-3 通信要素一:IP和端口号 InetAddress类测试 14-4 通信要素二:网络协议 14-5 TCP网络编程 TCP ...

  6. Java网络编程笔记4

    Socket和ServerSocket,网络编程可以分为创建Socket.打开连接Socket的输入流和输出流,对Socket进行编程,关闭Socket. 创建Socket 一个功能齐全的Socket ...

  7. 互联网学习(三):基于TCP协议的HTTP协议

    2007年,HTTPbis工作组的成立部分是为了修订和澄清HTTP / 1.1规范.2014年6月,工作组发布了一份更新的六部分规范,废弃了RFC 2616: RFC 7230,HTTP / 1.1: ...

  8. java网络编程(三)

    文章推荐 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 1.2.3 TCP编程 按照前面的介绍,网络通讯的方式有TCP和UDP两种,其中TCP方式的网络通 ...

  9. Java基础 - 网络编程 - InetAddress类、Socket(TCP)举例使用

    文章目录 InetAddress类 相关方法 代码举例 Socket 基本介绍 基本介绍2 应用案例(TCP字节流) 应用案例2(TCP字节流) 注意(结束标记) 应用案例3(TCP字符流) 注意(结 ...

  10. Java网络编程笔记1

    网络编程的基础知识 什么叫计算机网络,就是把分布在不同地理区域的计算机与专门的外部设备通信线路互连成一个规模大.功能强的网络系统. 计算机网络主要能做些以下功能: 1)资源共享 2)信息传输与集中处理 ...

最新文章

  1. UVa 311 - Packets
  2. Apache Spark源码走读之16 -- spark repl实现详解
  3. 第8章防范式编程上(代码大全3)
  4. 方便的管理苹果Mac上菜单栏图标软件推荐:Bartender
  5. 如何在 Mac 上控制对摄像头的访问?
  6. 智能直播审核方案:视频云智能业务截帧策略
  7. DB2数据库下载(v9.7/v10.5/v11.1)
  8. 软件的开发模型之瀑布型和快速原型
  9. 计算机表格填充,Excel表格的自动填充功能
  10. PyTorch | torch.manual_seed(1)是什么意思?torch随机数manual_seed(1)有什么用?如何理解torch.manual_seed(1)
  11. SX1278、SX1276、SX1262的简单详解
  12. 医疗图像处理与深度学习(二)
  13. 车企如何趟过「软件的坑」,大众集团或将在中国寻求收购
  14. 分布式配置管理平台Disconf
  15. a标签 rel属性
  16. 大型门户网站建设需要那些技术和注意事项
  17. 情感溢出:读《浣溪沙》
  18. 用matlab代码实现QDA,matlab数据库
  19. 如何摆脱打工人?注册申请163邮箱?尊享TOM VIP微信办公助手?
  20. 6.S081 Lab4 Traps

热门文章

  1. 1.17英文题面翻译
  2. 解决白天黑夜模式切换导致Fragment崩溃问题
  3. 25个 Vue 技巧,开发了5年了,有些竟然还是第一次见!
  4. 中科大计算机电子信息,中国科学技术大学电子工程与信息科学系
  5. poi excel密码加密
  6. 简单的python爬取淘宝数据
  7. 常用的OpenCV函数速查
  8. 租房高峰期,房产中介机构如何快速锁定客户?
  9. 我在华为的十年----徐家俊
  10. 为什么 Go 语言能在中国这么火?