Java Socket网络编程的经典例子

转载 2007年09月29日 01:29:00

   事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,Java SDK提供一些相对简单的Api来完成这些工作。Socket就是其中之一,对于Java而言,这些Api存在与java.net 这个包里面,因此只要导入这个包就可以准备网络编程了。 

  

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

 

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经典算法四十例编程详解+程序实例

[java] view plain copy JAVA经典算法40例   【程序1】   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第...
  • BillGates10001
  • BillGates10001
  • 2016年03月17日 10:39
  • 3637

【Java】Java之经典循环小例子

九九乘法表 * 文件名称: 九九乘法表 * 作 者: 廊坊师范学院 2013级 周家林 ...
  • mrlin6688
  • mrlin6688
  • 2015年11月30日 21:33
  • 691

Java多态性详细举例说明(很经典例子)

(一)相关类
  • free4294
  • free4294
  • 2014年09月04日 16:37
  • 27130

Java经典小案例(不定时更新)

人类除了擅长颓废,做什么都不对 1. 实现金字塔效果 import java.util.Scanner;/** * @author caojiantao-ext 根据输入的数目输出...
  • qq_15002323
  • qq_15002323
  • 2016年03月18日 10:37
  • 5604

Java经典算法四十例编程详解+程序实例

JAVA经典算法40例 【程序1】   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   1....
  • wangyang1354
  • wangyang1354
  • 2013年08月04日 15:14
  • 48934

Java一个多线程的经典例子

import java.io.*; //多线程编程  public class MultiThread    {  public static void main(String args[])  {...
  • wlchn
  • wlchn
  • 2015年08月10日 16:58
  • 235

java两种经典死锁例子,Lock发生死锁案列

第一种synchronized方式死锁,两个线程互相持有对方需要获取的锁。 第二种concurrent包Lock错误使用,导致死锁。 lock.unlock();释放锁使用地方不规范,导致死锁不能正常...
  • li396864285
  • li396864285
  • 2016年05月24日 10:06
  • 9876

Java socket通信实例,简单入门socket实例代码

是不是看了许多socket入门知识,却还是不能实际运用呢,这篇文章通过利用简单实例程序讲解通过socket实现客户端与服务器之间的通讯。这篇文章可以让你不需要了解socket原理也能利用,便于应急,但...
  • xxxtai
  • xxxtai
  • 2016年08月05日 12:42
  • 4006

Java一个简单的死锁例子

内容:一个简单的死锁例子,大概的思路:两个线程A和B,两把锁X和Y,现在A先拿到锁X,然后sleep()一段时间,我们知道sleep()是不会释放锁资源的。然后如果这段时间线程B拿到锁Y,也sleep...
  • u011345136
  • u011345136
  • 2015年05月16日 20:07
  • 1728

Java Socket网络编程的经典例子(转)

事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,Java SDK提供一些相对简单的Api来完成这些工作。Socket...
  • u011671986
  • u011671986
  • 2017年04月16日 13:53
  • 926
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java Socket网络编程的经典例子
举报原因:
原因补充:

(最多只允许输入30个字)