热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

java实现基于TCP协议网络socket编程(C/S通信)

这篇文章主要介绍了java实现基于TCP协议网络socket编程(CS通信),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、前言:TCP原理简介

首先,保证文章完整性,TCP的理论原理还是需要简介一下,略显枯燥๑乛◡乛๑。

TCP(传输控制协议,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP旨在适应支持多网络应用的分层协议层次结构。也就是说,TCP是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。

以上TCP的特点,也正是与UDP的明显不同之处。UDP(用户数据报协议)是一种无连接的、不可靠的、不以字节流传输通信协议。具体区别可对比之前这篇文章:

【基于UDP协议网络Socket编程(java实现C/S通信案例) 】 [https://www.jb51.net/article/198498.htm]

接着,“三次握手”则是众所周知的一个词,是建立TCP连接的重要过程。许多文章有详细解读,本篇则是详细记录在此原理之上,使用Java实现TCP的Socket网络通信,包含C/S软件架构的程序设计,偏向实践,更加有趣!

二、Socket编程通信

本篇使用Java进行Socket编程,Java的TCP/IP套接字编程将底层的细节进行了封装,其编程模型如图:

我们自顶向下观察,基于TCP的通信,必然有服务端Server和客户端Client。

首先,建立连接。两端分别有一个套接字Socket,用于两者之间的通信。客户端向服务器发送请求,创建socket进行连接。服务端则随时监听客户端发起的请求,接收并创建裂解Socket。

其次,开始通信。服务和客户两端的输入输出流互相通信。逻辑上可理解为通信进程的双方具有两个流(输出流和输入流)。逻辑上可将两个流理解为两个通信管道的全双工通信模式,一个用于向对方发送数据,另一个用于接收对方的数据。

最后,结束通信。客户端访问服务器结束,断开连接,关闭Socket和相关资源(输入输出流等)。服务端监听客户端状态,同时关闭Socket等连接。

建立通信规则:

Server和Client之间需要约定相同的规则,保证正常通信。之后的程序设计,我们约定:

客户端连接服务器,连接成功后,服务器首先给客户端发送一条欢迎信息;

客户端程序每发送一条信息给服务器,服务器接收并回送该信息到客户端,客户端接收并显示该信息;

当客户端发送"bye",则结束对话。

三、TCP服务器端(具体代码)

第一步,创建服务端套接字。

类成员变量:ServerSocket serverSocket,监听端口号port;

  private int port =8008;//服务器监听窗口
  private ServerSocket serverSocket;//定义服务器套接字

  public TCPServer() throws IOException{
    serverSocket =new ServerSocket(port);
    System.out.println("服务器启动监听在"+port+"端口...");

  }

第二步,定义输入输出流方法:

 private PrintWriter getWriter(Socket socket) throws IOException{
    //获得输出流缓冲区的地址
    OutputStream socketOut=socket.getOutputStream();
    //网络流写出需要使用flush,这里在printWriter构造方法直接设置为自动flush
    return new PrintWriter(new OutputStreamWriter(socketOut,"utf-8"),true);
  }

  private BufferedReader getReader(Socket socket) throws IOException{
    //获得输入流缓冲区的地址
    InputStream socketIn=socket.getInputStream();
    return new BufferedReader(new InputStreamReader(socketIn,"utf-8"));
  }

 第三步,服务端核心:

//单客户版本,每次只能与一个用户建立通信连接
public void Service(){
  while (true){
    Socket socket=null;
    try {
      //此处程序阻塞,监听并等待用户发起连接,有连接请求就生成一个套接字
      socket=serverSocket.accept();

      //本地服务器控制台显示客户连接的用户信息
      System.out.println("New connection accepted:"+socket.getInetAddress());
      BufferedReader br=getReader(socket);//字符串输入流
      PrintWriter pw=getWriter(socket);//字符串输出流
      pw.println("来自服务器消息:欢迎使用本服务!");

      String msg=null;
      //此处程序阻塞,每次从输入流中读入一行字符串
      while ((msg=br.readLine())!=null){
        //如果用户发送信息为”bye“,就结束通信
        if(msg.equals("bye")){
          pw.println("来自服务器消息:服务器断开连接,结束服务!");
          System.out.println("客户端离开。");
          break;
        }
        pw.println("来自服务器消息:"+msg);
      }
    }catch (IOException e){
      e.printStackTrace();
    }finally {
      try {
        if (socket!=null)
          socket.close();//关闭socket连接以及相关的输入输出流
      }catch (IOException e){
        e.printStackTrace();
      }
    }
  }
}

 代码关键解析很清楚易懂。可以看到,服务端提供服务放到了一个While(true)里面,这是因为服务器程序需要一直运行,所以处理代码一般放在while(true)这种无限循环中,TCPServer运行一次,且自身不能终止运行,要终止它运行,只能通过强制方式(如在IDE环境强制关闭)。

四、TCP客户端(具体代码)

第一步,创建客户端套接字,定义类构造方法,实现输入输出流。

//单客户版本,每次只能与一个用户建立通信连接
public void Service(){
  while (true){
    Socket socket=null;
    try {
      //此处程序阻塞,监听并等待用户发起连接,有连接请求就生成一个套接字
      socket=serverSocket.accept();

      //本地服务器控制台显示客户连接的用户信息
      System.out.println("New connection accepted:"+socket.getInetAddress());
      BufferedReader br=getReader(socket);//字符串输入流
      PrintWriter pw=getWriter(socket);//字符串输出流
      pw.println("来自服务器消息:欢迎使用本服务!");

      String msg=null;
      //此处程序阻塞,每次从输入流中读入一行字符串
      while ((msg=br.readLine())!=null){
        //如果用户发送信息为”bye“,就结束通信
        if(msg.equals("bye")){
          pw.println("来自服务器消息:服务器断开连接,结束服务!");
          System.out.println("客户端离开。");
          break;
        }
        pw.println("来自服务器消息:"+msg);
      }
    }catch (IOException e){
      e.printStackTrace();
    }finally {
      try {
        if (socket!=null)
          socket.close();//关闭socket连接以及相关的输入输出流
      }catch (IOException e){
        e.printStackTrace();
      }
    }
  }
}

第二步,实现网络通信发送和接收方法。

  public void send(String msg){
    //输出字符流,由socket调用系统底层函数,经网卡发送字节流
    pw.println(msg);
  }

  public String receive(){
    String msg=null;
    try {
      //从网络输入字符流中读取信息,每次只能接受一行信息
      //不够一行时(无行结束符),该语句阻塞
      //直到条件满足,程序往下运行
      msg=br.readLine();
    }catch (IOException e){
      e.printStackTrace();
    }
    return msg;
  }

 第三步,定义网络连接关闭方法供外部调用。

 public void close(){
    try {
      if (socket!=null)
        socket.close();
    }catch (IOException e){
      e.printStackTrace();
    }
  }

TCP连接的释放也有“四次握手”一说,必须经过2MSL后才真正释放。具体过程如下图:

五、通信效果演示

GIF动图演示:

六、“创意”机器人:价值一个亿的AI核心代码(具体代码)

这部分我们要实现“聊天机器人”,效果这样:

是不是迫不及待想知道如何实现呢!堪称“价值一个亿的AI核心代码”!!??

就这样实现了!

 不卖关子了,就一行代码!

msg=msg.replace("?","!").replace("?","!").replace("吗","").replace("吗?","");

具体想实现机器人如何回复可以自行调整代码。

七、最后

本篇则是详细记录在此原理之上,使用Java实现TCP的Socket网络通信,包含C/S软件架构的程序设计,偏向实践,更加有趣!仔细阅读的朋友可以发现,在服务器端核心部分,有一行注释说明了该程序只支持单用户,也就是单线程通信,可以尝试一下,如果再开一个客户端连接该服务,是否因为单线程阻塞程序卡住了。

这个问题关键就在于:服务器和客户端互相约定通信规则,否则就可能有问题,例如,如果服务器在一个客户端连接成功后,并没有一条信息发送给客户端,客户端的读取欢迎信息的语句无法读取到内容,就被阻塞住,由于是单线程,甚至整个程序都会被卡住。要解决这个问题,等待更新下一篇!

另外,UI界面的设计可参考上一篇博客:【基于UDP协议网络Socket编程(java实现C/S通信案例) 】 [https://www.jb51.net/article/198498.htm]

到此这篇关于java实现基于TCP协议网络socket编程(C/S通信)的文章就介绍到这了,更多相关java TCP协议socket编程内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 电销机器人作为一种人工智能技术载体,可以帮助企业提升电销效率并节省人工成本。然而,电销机器人市场缺乏统一的市场准入标准,产品品质良莠不齐。创业者在代理或购买电销机器人时应注意谨防用录音冒充真人语音通话以及宣传技术与实际效果不符的情况。选择电销机器人时需要考察公司资质和产品品质,尤其要关注语音识别率。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 本文介绍了在CentOS 7.x上进行端口映射配置的方法,通过修改内核和配置防火墙实现端口映射。作者分享了自己使用华为服务器进行端口映射的经验,发现网速比直连还快且稳定。详细的配置过程包括开启系统路由模式功能、设置IP地址伪装、设置端口映射等。同时,还介绍了如何监听本地端口的tcp请求,以及删除规则和开放的端口的方法。 ... [详细]
  • 缤果串口网络蓝牙调试助手的特点和下载链接
    本文介绍了缤果串口网络蓝牙调试助手的主要特点,包括支持常用的波特率、校验、数据位和停止位设置,以及以ASCII码或十六进制接收或发送数据或字符的功能。该助手还能任意设定自动发送周期,并能将接收数据保存成文本文件。同时,该软件支持网络UDP/TCP和蓝牙功能。最后,提供了腾讯微云和百度网盘的下载链接。 ... [详细]
  • 统一知识图谱学习和建议:更好地理解用户偏好
    本文介绍了一种将知识图谱纳入推荐系统的方法,以提高推荐的准确性和可解释性。与现有方法不同的是,本方法考虑了知识图谱的不完整性,并在知识图谱中传输关系信息,以更好地理解用户的偏好。通过大量实验,验证了本方法在推荐任务和知识图谱完成任务上的优势。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • Python15行代码实现免费发送手机短信,推送消息「建议收藏」
    Python15行代码实现免费发 ... [详细]
  • 3年半巨亏242亿!商汤高估了深度学习,下错了棋?
    转自:新智元三年半研发开支近70亿,累计亏损242亿。AI这门生意好像越来越不好做了。近日,商汤科技已向港交所递交IPO申请。招股书显示& ... [详细]
author-avatar
男人吧总负责人千金
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有