服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

比尔学java:java socket篇


  比尔最近接到一个项目,是要在原来的系统上实现客户端与服务器的连接。原来的系统是用java开发的,项目组讨后,决定应用java提供的socket类来解决问题。比尔是c开发的高手,对java却只略知皮毛。所以,比尔一头扎进java中,开始他的学习历程。当然,首先还要解决眼前的问题,学习socket编程。
  在学习socket编程之前,先看看自己是否熟悉tcp、udp、ports等网络基本概念,要是还不熟悉的话就得先去补补课罗!
  socket 的基本概念
  1、socket,也就是俗称的套接字。
  2、sun java中的定义:是运行在网络上的两个程序间双向通讯连接的末端,它提供客户端和服务器端的连接通道。socket绑定于特定端口这样tcp层就知道将数据提供给哪个应用程序。
  3、字面上的理解,socket的意思是"插座、孔",你还可以把它形象地理解为打电话用的电话机,你从听筒里听到对方声音,同时将声音通过话筒传给对方。
  
  我想你现在和我刚开始的时候一样:好像有点明白,又好像不是很明白,没关系,我希望通过下面例子的讲解你能够彻底地掌握它。在实例之前,让我们先来看看socket实现的基本原理。
  socket编程实现原理
  从连接的建立到连接的结束,每个socket应用都大致包含以下几个基本步骤:
  1、服务器端socket绑定于特定端口,服务器侦听socket等待连接请求;
  2、客户端向服务器和特定端口提交连接请求;
  3、服务器接受连接,产生一新的socket,绑定到另一端口,由此socket来处理和客户端的交互,服务器继续侦听原socket来接受其他客户端的连接请求;
  
  4、连接成功后客户端也产生一socket,并通过它来与服务器端通讯(注意:客户端socket并不与特定端口绑定);
  5、接下来,服务器端和客户端就通过读取和写入各自的socket来进行通讯。
  注意:本文中只讲解基于tcp的socket应用
  java中的socket类
  java中提供两个类(在java.net包中)――socket和serversocket来分别实现客户端和服务器端socket。但socket的实际工作是由抽象类socketimpl的实例来完成的,这其实是设计模式中abstract factory模式的一个应用。
  
  serversocket类的常用构造器和主要方法:
  
  serversocket(int port) 在指定的端口号上产生一服务器端socket
  socket accept()
  侦听socket,接受连接
  socket类的常见构造器和主要方法:
  
  socket(string host, int port) 生成一socket并连接至指定的主机和端口
  inputstream getinputstream() 返回socket的输入流
  outputstream getouputstream() 返回socket的输出流
  一个客户服务器实例
  了解了上面的一些基本知识以后,我想大家现在都迫不及待地想亲自动手编写自己的socket,那就让我们开始吧!在这个例子中,我们模仿了一个echo服务,它侦听3333端口。客户端接受用户键盘输入并向服务器端发出连接请求,服务器端接受客户端连接,连接成功后建立会话,客户端于是向服务器端发送用户输入信息,服务器端接收此信息并且简单返回给客户端。源码如下:
  
  (服务器端)
  
  /**
   * <p>title:echoserver.java </p>
   * <p>description: echoserver create a echo-like server at port 3333</p>
   * @author mac
   * @version 2002/9/2
   */
  
  import java.net.*;
  import java.io.*;
  
  public class echoserver
  {
   public static void main (string[] args) throws ioexception
   {
   serversocket echoserver = null;
   try
   {
   echoserver = new serversocket(3333); //creat a server socket at port
  3333(问题一)
   }
   catch(ioexception e)
   {
   system.err.println("couldn't listen on port:3333");
   system.exit(-1);
   }
  
   socket echoclient = null;
   try
   {
   echoclient = echoserver.accept(); //accept a connection
   }
   catch(ioexception e)
   {
   system.err.println("io error:" + e.getmessage());
   system.exit(-1);
   }
  
   printwriter out = new printwriter(echoclient.getoutputstream(),true);
   //gets the socket's output stream and opens a printwriter on it
   //if you remove the argument true,what will happen?(问题三)
   bufferedreader in = new bufferedreader(
   new inputstreamreader(echoclient.getinputstream()));
   //gets the socket's input stream and opens a bufferedreader on it
   string strfromclient;
  
   while((strfromclient = in.readline()) != null)
   {
   out.println("result is :" + strfromclient);
   }
  
   in.close();
   out.close();
   echoclient.close();
   echoserver.close();
   }
  }
  
  (客户端)
  /**
   *<p>title:echoclient.java </p>
   *<p>description: echoclient creates a socket thereby getting a connection to
  echo-like server</p>
   * @author mac wang
   * @version 2002/8/30
   */
  
  import java.net.*;
  import java.io.*;
  
  public class echoclient
  {
  
   public static void main(string[] args)
   {
   try
   {
  socket echoclient = new socket("yourhostname",3333);
  //creat a new socket connected to host and port 3333
   printwriter out = new printwriter(echoclient.getoutputstream(),true);
  
   bufferedreader in = new bufferedreader(
   new inputstreamreader(echoclient.getinputstream()));
   string fromserver,fromuser;
   bufferedreader stdin = new bufferedreader(
   new inputstreamreader(system.in));
   //gets the system input stream and opens a bufferedreader on it
   while ((fromuser = stdin.readline()) != null)
   {
   if (fromuser.equals("bye")) break;
  //when user types "bye" then end
  
   system.out.println("input is:" + fromuser);
   out.println(fromuser);
  
   fromserver = in.readline();
   system.out.println(fromserver);
   }
   out.close();
   in.close();
   echoclient.close();
   }
   catch(unknownhostexception e)
   {
   system.err.println("unknown host:yourhostname");
   system.exit(1);
   }
   catch(ioexception e)
   {
   system.err.println("i/0 error:" + e.getmessage());
   system.exit(1);
   }
   }
  }
  现在大家可以分别运行server和client,看看程序运行效果(注意:你必须将yourhostname替换成你自己的主机名或ip地址)。并且思考以下几个问题:
  
  1、把端口号换成2222后看看程序运行效果?那么89呢?是不是任何数字都可以呢?
  
  2、如果不采用我们自己编写的echo server,而是连接到系统本身提供的echo server(端口号为7),试试看会发生什么情况,客户端socket是否需要改变呢?
  
  3、去掉printwriter中的参数true,看看程序运行的效果?
  
  4、注意程序中是如何读取和写入socket的?
  5、试着多打开几个客户端,看看效果如何?
  从问题5中大家可以看出来,上面的例子只支持一个用户连接,那么如何支持多用户的同时访问呢?最简单有效的方法就是利用多线程实现,每个线程对应一个用户连接,server接受一个client连接后,就新产生一个线程,并交由它去处理余下的工作。下面就是支持多用户的服务器端实现:
  /**
  *<p>title:echomultiserver </p>
   *<p>description: echoserver create a echo-like server at port 3333 which supports
  multi-client</p>
   * @author mac wang
   * @version 2002/9/2
   */
  import java.net.*;
  import java.io.*;
  class echomultiserverthread extends thread
  {
   private socket echoclient = nul

扫描关注微信公众号