`

Java Socket 初步详解

阅读更多

网络编程的基本模型就是客户机到服务器模型,简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置,而另一个则只需要知道这个固定的位置。并去建立两者之间的联系,然后完成数据的通讯就可以了,这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端,基于这个简单的模型,就可以进入网络编程啦。

  Java对这个模型的支持有很多种Api,而这里我只想介绍有关Socket的编程接口,对于Java而言已经简化了Socket的编程接口。首先我们来讨论有关提供固定位置的服务方是如何建立的。Java提供了ServerSocket来对其进行支持.事实上当你创建该类的一个实力对象并提供一个端口资源你就建立了一个固定位置可以让其他计算机来访问你,ServerSocket server=new ServerSocket(6789);这里稍微要注意的是端口的分配必须是唯一的。因为端口是为了唯一标识每台计算机唯一服务的,另外端口号是从0~65535之间的,前1024个端口已经被Tcp/Ip 作为保留端口,因此你所分配的端口只能是1024个之后的。好了,我们有了固定位置.现在所需要的就是一根连接线了.该连接线由客户方首先提出要求。因此Java同样提供了一个Socket对象来对其进行支持,只要客户方创建一个Socket的实例对象进行支持就可以了。Socket client
=new Socket(InetAddress.getLocalHost(),5678);客户机必须知道有关服务器的IP地址,对于着一点Java也提供了一个相关的类InetAddress 该对象的实例必须通过它的静态方法来提供,它的静态方法主要提供了得到本机IP 和通过名字或IP直接得到InetAddress的方法。

  上面的方法基本可以建立一条连线让两台计算机相互交流了,可是数据是如何传输的呢?事实上I/O操作总是和网络编程息息相关的。因为底层的网络是继续数据的,除非远程调用,处理问题的核心在执行上,否则数据的交互还是依赖于IO操作的,所以你也必须导入java.io这个包.java的IO操作也不复杂,它提供了针对于字节流和Unicode的读者和写者,然后也提供了一个缓冲用于数据的读写。

BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out=new PrintWriter(server.getOutputStream());


  上面两句就是建立缓冲并把原始的字节流转变为Unicode可以操作,而原始的字节流来源于Socket的两个方法,getInputStream()和getOutputStream()方,分别用来得到输入和输出,那么现在有了基本的模型和基本的操作工具,我们可以做一个简单的Socket例程了.

  服务方:

import java.io.*;
import java.net.*;
public class MyServer {
 public static void main(String[] args) throws IOException{
  ServerSocket server=new ServerSocket(5678);
  Socket client=server.accept();
  BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
  PrintWriter out=new PrintWriter(client.getOutputStream());
  while(true){
   String str=in.readLine();
   System.out.println(str);
   out.println("has receive....");
   out.flush();
   if(str.equals("end"))
    break;
  }
  client.close();
 }
}


  这个程序的主要目的在于服务器不断接收客户机所写入的信息只到,客户机发送"End"字符串就退出程序,并且服务器也会做出"Receive"为回应,告知客户机已接收到消息。

  客户机代码:

import java.net.*;
import java.io.*;

public class Client{
 static Socket server;

 public static void main(String[] args)throws Exception{
  server=new Socket(InetAddress.getLocalHost(),5678);
  BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
  PrintWriter out=new PrintWriter(server.getOutputStream());
  BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));

  while(true){
   String str=wt.readLine();
   out.println(str);
   out.flush();
   if(str.equals("end")){
    break;
   }
   System.out.println(in.readLine());
  }
  server.close();
 }
}


  客户机代码则是接受客户键盘输入,并把该信息输出,然后输出"End"用来做退出标识。

  这个程序只是简单的两台计算机之间的通讯,如果是多个客户同时访问一个服务器呢?你可以试着再运行一个客户端,结果是会抛出异常的。那么多个客户端如何实现呢?

  其实,简单的分析一下,就可以看出客户和服务通讯的主要通道就是Socket本身,而服务器通过accept方法就是同意和客户建立通讯.这样当客户建立Socket的同时。服务器也会使用这一根连线来先后通讯,那么既然如此只要我们存在多条连线就可以了。那么我们的程序可以变为如下:

  服务器:

import java.io.*;
import java.net.*;

public class MyServer {
 public static void main(String[] args) throws IOException{
  ServerSocket server=new ServerSocket(5678);
  while(true){
   Socket client=server.accept();
   BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
   PrintWriter out=new PrintWriter(client.getOutputStream());
   while(true){
    String str=in.readLine();
    System.out.println(str);
    out.println("has receive....");
    out.flush();
    if(str.equals("end"))
     break;
   }
   client.close();
  }
 }
}


  这里仅仅只是加了一个外层的While循环,这个循环的目的就是当一个客户进来就为它分配一个Socket直到这个客户完成一次和服务器的交互,这里也就是接受到客户的"End"消息.那么现在就实现了多客户之间的交互了。但是.问题又来了,这样做虽然解决了多客户,可是是排队执行的。也就是说当一个客户和服务器完成一次通讯之后下一个客户才可以进来和服务器交互,无法做到同时服务,那么要如何才能同时达到既能相互之间交流又能同时交流呢?很显然这是一个并行执行的问题了。所以线程是最好的解决方案。

  那么下面的问题是如何使用线程.首先要做的事情是创建线程并使得其可以和网络连线取得联系。然后由线程来执行刚才的操作,要创建线程要么直接继承Thread要么实现Runnable接口,要建立和Socket的联系只要传递引用就可以了.而要执行线程就必须重写run方法,而run方法所做的事情就是刚才单线程版本main所做的事情,因此我们的程序变成了这样:

import java.net.*;
import java.io.*;

public class MultiUser extends Thread{
 private Socket client;

 public MultiUser(Socket c){
  this.client=c;
 }

 public void run(){
  try{
   BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
   PrintWriter out=new PrintWriter(client.getOutputStream());
   //Mutil User but can't parallel
   while(true){
    String str=in.readLine();
    System.out.println(str);
    out.println("has receive....");
    out.flush();
    if(str.equals("end"))
     break;
   }
   client.close();
  }catch(IOException ex){
  }finally{
 }
}

public static void main(String[] args)throws IOException{
 ServerSocket server=new ServerSocket(5678);
 while(true){
  //transfer location change Single User or Multi User
  MultiUser mu=new MultiUser(server.accept());
  mu.start();
 }
}
}


  我的类直接从Thread类继承了下来.并且通过构造函数传递引用和客户Socket建立了联系,这样每个线程就有了。一个通讯管道.同样我们可以填写run方法,把之前的操作交给线程来完成,这样多客户并行的Socket就建立起来了。

分享到:
评论

相关推荐

    JAVA-socket开发指南

    ### JAVA-socket开发指南知识点详解 #### 一、教程简介与目标读者 本文档主要针对初学者介绍Java中Socket编程的基础知识以及实际应用案例。如果你是刚接触Socket编程的新手,希望通过Java语言来掌握Socket的基本...

    服装销售系统java swing

    《基于Java Swing的服装销售系统详解》 在IT领域,开发用户友好的应用程序是至关重要的。对于初学者来说,理解并应用面向对象编程思想、掌握GUI(图形用户界面)设计以及数据库管理是基础技能的基石。本文将深入...

    C/S模式下的java图书管理系统

    《C/S模式下的Java图书管理系统详解》 C/S(Client/Server)模式是一种常见的软件架构模式,它将应用逻辑分为客户端(Client)和服务器端(Server)两部分,客户端负责用户交互,服务器端则处理数据存储和管理。在...

    课程设计_聊天文件java_java_java聊天室_

    【Java聊天室实现详解】 Java聊天室是一种基于网络通信的多用户交互系统,它允许用户在同一个平台上进行实时文本交流。本课程设计旨在通过构建一个简单的Java聊天室,帮助学习者掌握Java网络编程、多线程和文件传输...

    Micaps Java开发

    在描述中提到的"Java开发代码,不是很全,但是框架基本做出来了",这意味着我们可能面对的是一个初步成型的Micaps Java项目框架,虽然不完整,但已经具备了核心功能。对于初学者或者希望深入理解Micaps Java开发的...

    Thinking in Java Fourth Edition

    - **Socket编程**:详解如何使用Socket进行网络通信。 - **服务器端与客户端编程**:对比服务器端和客户端编程的不同特点。 #### 第16章 设计范式 - **设计模式概述**:介绍几种常见的设计模式及其适用场景。 - **...

    MIDP2.0端到端socket编程案例

    **MIDP2.0端到端Socket编程案例详解** MIDP(Mobile Information Device Profile)2.0是Java 2 Micro Edition(J2ME)的一部分,主要用于开发移动设备应用程序,如手机和平板电脑。在MIDP2.0中,Socket编程允许设备...

    北京阅联信息技术有限公司Java笔试题

    【标题】:“北京阅联信息技术有限公司Java笔试题”通常是一场技术面试的初步阶段,旨在评估应聘者对Java编程语言的理解、应用能力以及问题解决技巧。这类笔试题可能涵盖Java的基础概念、语法特性、面向对象编程、...

    单机/网络板俄罗斯方块java

    《单机/网络板俄罗斯方块Java实现详解》 俄罗斯方块,这款经典的电子游戏,以其简洁的游戏机制和无尽的挑战性深受全球玩家喜爱。本文将深入探讨如何使用Java编程语言来实现单机版以及网络多人对战的俄罗斯方块。...

    java1000题基础百战程序员

    ### Java1000题基础百战程序员知识点详解 #### 一、JavaSE编程基础概述 - **初识Java** - Java的历史和发展背景 - Java的特点:平台无关性、面向对象、安全性等 - Java开发环境的搭建:JDK安装与配置 - Hello ...

    Android Native Crash分析详解

    ### Android Native Crash分析详解 #### 一、何为Native Crash 简单来说,Native Crash是指发生在native层的用户进程崩溃现象。在Android系统中,根据不同的层次可以将Native Crash大致分为以下四类: 1. **Java...

    Jdk新特性教程吐血整理干货.md

    - **Switch 表达式**:Java 12 引入了对 `switch` 表达式的初步支持,这是一种更简洁的写法,可以返回一个值。 ##### Unicode 11 支持 - **Unicode 支持**:Java 12 扩展了其字符集支持,增加了对 Unicode 11 的...

    C/S结构的酒店管理系统

    1. **C/S架构详解**:在C/S架构中,客户端通常安装在用户的计算机上,提供直观的用户界面,允许用户进行操作。服务器端则运行在一台或多台专门的计算机上,处理来自多个客户端的请求。这种架构的优势在于能够提供更...

    tomcat的工作原理

    - **状态码100的使用**:这是对某些POST请求的初步确认,表示服务器已经接收到请求头,但尚未处理请求体。 2. **容器(Containers)**:容器是Tomcat的核心,用于装载和管理Web应用程序。容器可以分为四个层次:...

    java版基于UDP协议网上聊天程序课程设计报告.doc

    在设计过程中,可能需要使用Java的Socket编程API来实现UDP通信。 **系统功能框图和流程图**: 这部分通常会包含服务器和客户端的工作流程,以及数据在网络中的传输路径。在流程图中,可能会显示客户端如何创建UDP...

Global site tag (gtag.js) - Google Analytics