套接字

套接字概述

网络通信使用IP地址标识Internet上的计算机,使用端口号标识服务器上的进程(程序)。也就是说,如果服务器上的一个程序不占用一个端口号,用户程序就无法找到它,就无法和该程序交互信息。端口号规定为一个16位的0-65535之间的整数,其中,0~1023被预先定义的服务通信占用(如telnet占用端口23,http占用端口80等),除非需要访问这些特定服务,否则,就应该使用1024-65535这些端口中的某一个进行通信,以免发生端口冲突。

当两个程序需要通信时,它们可以通过使用Socket 类建立套接字对象并连接在一起(端口号与IP地址的组合得出一个网络套接字),本节将讲解怎样将客户端和服务器端的套接字对象连接在一起来交互信息。

熟悉生活中的一些常识对于学习、理解以下套接字的讲解是非常有帮助的,比如,有人让你去“中关村邮局”,你可能反问“我去做什么”,因为他没有告知你“端口”,你觉得不知处理何种业务。他说:“中关村邮局,8号窗口”,那么你到达地址“中关村邮局”,找到“8号”窗口,就知道8号窗口处理特快专递业务,而且,必须有个先决条件,就是你到达“中关村邮局,8号窗口”时,该窗口必须有一位业务员在等待客户,否则就无法建立交互业务。

客户端套接字

客户端程序使用Socket类建立负责连接到服务器的套接字对象。

Socket的构造方法是Socket (String host, int port),参数host是服务器的IP地址,port是一个端口号。建立套接字对象可能发生IOException异常,因此应像下面那样建立连接到服务器的套接字对象:

    try {      Socket clientSocket = new Socket("http://192.168.0.78",2010);    }    catch (IOException e) {}

当套接字对象clientSocket建立后,clientSocket可以使用方法getInputStream()获得一个输入流,这个输入流的源和服务器端的一个输出流的目的地刚好相同,因此客户端用输入流可以读取服务器写入到输出流中的数据;clientSocket使用方法getOutputStream()获得一个输出流,这个输出流的目的地和服务器端的一个输入流的源刚好相同,因此服务器用输入流可以读取客户写入到输出流中的数据。

ServerSocket对象

与服务器端套接字

我们已经知道客户负责建立连接到服务器的套接字对象,即客户负责呼叫。为了能使客户成功地连接到服务器,服务器必须建立一个ServerSocket对象(像生活中邮局窗口的业务员),该对象通过将客户端的套接字对象和服务器端的一个套接字对象连接起来,从而达到连接的目的。

ServerSocket的构造方法是ServerSocket (int port),port是一个端口号。port必须和客户呼叫的端口号相同。当建立ServerSocket对象时可能发生IOException异常,因此应像下面那样建立ServerSocket对象。

    try {      ServerSocket serverForClient = new ServerSocket(2010);    }    catch(IOException e) {}

比如,2010端口已被占用时,就会发生IOException异常。

当服务器的ServerSocket对象serverForClient建立后,就可以使用方法accept()将客户端的套接字和服务器端的套接字连接起来,代码如下所示。

    try {      Socket sc = serverForClient.accept();    }    catch(IOException e) {}

所谓“接收”客户的套接字连接是指serverForClient(服务器端的ServerSocket对象)调用accept()方法会返回一个和客户端Socket对象相连接的Socket对象sc,sc驻留在服务器端,这个Socket对象sc调用getOutputStream()获得的输出流将指向客户端Socket对象的输入流,即服务器端的输出流的目的地和客户端输入流的源刚好相同;同样,服务器端的这个Socket对象sc调用getlnputStream()获得的输入流将指向客户端Socket对象的输出流,即服务器端的输入流的源和客户端输出流的目的地刚好相同。因此,当服务器向输出流写入信息时,客户端通过相应的输入流就能读取,反之亦然,如下图所示。

需要注意的是,从套接字连接中读取数据与从文件中读取数据有着很大的不同,尽管二者都是输入流。从文件中读取数据时,所有的数据都已经在文件中了。而使用套接字连接时,可能在另一端数据发送之前,就已经开始读取了,这时,就会阻塞本线程,直到该读取方法成功读取到信息,本线程才继续执行后续的操作。

另外,需要注意的是accept方法也会阻塞线程的执行,直到接收到客户的呼叫。也就是说,如果没有客户呼叫服务器,那么下述代码中的System.out.println("hello");不会被执行。

    try {      Socket sc= serverForClient.accept();      System.out.println("hello");    }    catch(IOException e) {}

连接建立后,服务器端的套接字对象调用getInetAddress()方法可以获取一个InetAddess对象,该对象含有客户端的IP地址和域名,同样,客户端的套接字对象调用getlnetAddress()方法可以获取一个InetAddess对象,该对象含有服务器端的IP地址和域名。

双方通信完毕后,套接字应使用close()方法关闭套接字连接。

注:ServerSocket对象可以调用setSoTimeout(int timeout)方法设置超时值(单位是毫秒),timeout是一个正值,当ServerSocket对象调用accept方法阻塞的时间一旦超过timeout时,将触发SocketTimeoutException。

下面通过一个简单的例子说明上面讲的套接字连接。在例子3中,客户端向服务器端问了三句话,服务器都一一给出了回答。首先将例子3中服务器端的Server.java编译通过,并运行起来,等待客户的呼叫,然后运行客户端程序。程序代码如下所示:

①客户端

import java.io.*;import java.net.Socket;public class Client {  public static void main(String[] args) {    String [] mess = {"2010世界杯在哪举行?","巴西进入世界杯了吗?","中国进入世界杯了吗?"};    Socket mysocket;    DataInputStream in = null;    DataOutputStream out = null;    try {      mysocket = new Socket("127.0.0.1",2010);      in= new DataInputStream(mysocket.getInputStream());      out = new DataOutputStream (mysocket.getOutputStream());      for(int i=0;i        out.writeUTF(mess[i]);        String s=in.readUTF();   //in读取信息,阻塞状态        System.out.println("客户收到服务器的回答:"+s);        Thread.sleep(500);      }    }    catch (Exception e) {      System.out.println("服务器已断开"+e);    }  }}

②服务器端

import java.io.*;import java.net.*;public class Server {  public static void main(String[] args) {    String [] answer = {"南非","进入世界杯了","哈哈……问题真逗!"};    ServerSocket serverForClient = null;    Socket socketOnServer = null;    DataOutputStream out = null;    DataInputStream in = null;    try {      serverForClient = new ServerSocket(2010);    }    catch (IOException el) {      System.out.println(el);    }    try {      System.out.println("等待客户呼叫");      socketOnServer = serverForClient.accept();  //阻塞状态,除非有客户呼叫      out = new DataOutputStream(socketOnServer.getOutputStream());      in = new DataInputStream(socketOnServer.getInputStream());      for(int i=0;i        String s = in.readUTF(); //in读取信息,阻塞状态        System.out.println("服务器收到客户的提问:"+s);        out.writeUTF(answer[i]);        Thread.sleep(500);      }    }    catch (Exception e) {      System.out.println("客户已断开"+e);    }  }}

客户端运行效果如图所示:

服务器端运行效果如图所示:

mysal向一个无法连接的网络尝试了一个套接字操作 0.0.3.235_第十二章 Java网络编程(3)——套接字(上)...相关推荐

  1. 第十二章_网络搭建及训练

    文章目录 第十二章 网络搭建及训练 CNN训练注意事项 第十二章 TensorFlow.pytorch和caffe介绍 12.1 TensorFlow 12.1.1 TensorFlow是什么? 12 ...

  2. 第十六章 ConvNeXt网络详解

    系列文章目录 第一章 AlexNet网络详解 第二章 VGG网络详解 第三章 GoogLeNet网络详解 第四章 ResNet网络详解 第五章 ResNeXt网络详解 第六章 MobileNetv1网 ...

  3. DayDayUp:《机器崛起前传》第二十二章【蹒跚而来】读后感(文章源自网络)—听课笔记

    DayDayUp:<机器崛起前传>第二十二章[蹒跚而来]读后感(文章源自网络)-听课笔记 <机器崛起前传> 1.机器岂不能有自我?         计算机的发展历程可谓蹒跚.从 ...

  4. 【十五】Java网络编程思维导图

    知识章节参考:[十五]Java网络编程

  5. 向一个无法连接的网络尝试了一个套接字操作_python3从零学习-5.8.1、socket—底层网络接口...

    源代码: Lib/socket.py 这个模块提供了访问BSD*套接字*的接口.在所有现代Unix系统.Windows.macOS和其他一些平台上可用. 这个Python接口是用Python的面向对象 ...

  6. Java 第十二章.网络编程

    网络编程 1.概述 2.网络通信要素概述 3.通信要素1:IP和端口号 3.1IP 3.2端口号 4.通信要素2:网络协议 5.TCP网络编程 6.UDP网络编程 7.URL编程 1.概述 Java是 ...

  7. TCP/IP详解 第十二章(9) TCP断开连接

    前言 不管面试 Java .C/C++.Python 等开发岗位, TCP 的知识点可以说是的必问的了. 任 TCP 虐我千百遍,我仍待 TCP 如初恋. 遥想小林当年校招时常因 TCP 面试题被刷, ...

  8. 第十二章:email-mailbox:管理email归档-imaplib:IMAP4客户库-连接服务器(认证失败)

    13.4.2 连接服务器 要建立与一个IMAP服务器的连接,有2个步骤.首先,建立套接字连接本身.其次,用服务器上的一个账户认证为用户.下面的示例代码会从一个配置文件读取服务器和用户信息. impor ...

  9. c++程序设计十二章第5题5 写一个程序,定义抽象基类shape由它派生出5个派生类:Circle(圆形),Square(正方形),Rectangle(矩形),Trapezoid(梯形),Tr

    写一个程序,定义抽象基类shape由它派生出5个派生类:Circle(圆形),Square(正方形),Rectangle(矩形),Trapezoid(梯形),Triangle(三角形).用虚函数分别计 ...

最新文章

  1. JAVA的输入输出基本操作样例
  2. 驰骋工作流引擎是如何实现自动更新的?
  3. Faster R-CNN论文笔记——FR
  4. Hadoop HA+Federation 高可用联邦模式搭建指南
  5. 【面向过程编程】零钱通项目
  6. AV1挑起的Codec之战
  7. 【转】wpf从我炫系列2----布局控件的使用(下)
  8. php删除第一个字母,php – 正在上传的文件将第一个字母切断
  9. zibll子比主题v5.4免授权修复版
  10. ajax onload怎么用,Ajax中onload和onreadystatechange两种请求方式的区别
  11. 架构系列一:大型项目架构演进过程
  12. Go语言备忘录(1):基本数据结构
  13. 计算机速录专业教学计划,计算机信息与速录技术专业二年制教学计划.doc
  14. IMSIDesign.TurboCAD.Designer.v14
  15. 未来五年你永远不会忘记的最佳GameCube仿真器
  16. js 生成二维码(qrcodejs)
  17. 整流二极管的细节分析
  18. 开源项目推荐:物联网消息引擎EMQ X/大数据平台TDengine/可视化平台Grafana/dgiot
  19. 基于蜂群对花蜜需求所做的数量模型构建及分析
  20. 尼尔机器人技能快捷键_尼尔机械纪元出招表及招式使用技巧 尼尔机械纪元技能怎么用...

热门文章

  1. 防止过拟合,采用的手段有哪些?
  2. yaml语法--多行字符串可以使用|保留换行符,也可以使用>折叠换行
  3. python报错:ModuleNotFoundError: No module named ‘tkinter‘ 解决办法
  4. sealos包管理使用
  5. linux通过tar包安装docker
  6. jvm调优:何为垃圾及与c++的对比
  7. Scala \和%运算小案例
  8. eureka服务下线事件监听(自定义处理逻辑)
  9. Solr的安装步骤及增删改查代码示例
  10. MySQL优化关联查询