事实上网络编程 简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,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的读者和写者,然后也提供了一个缓冲用于数据的读写。
重要的Socket API:
java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。
. Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
. getInputStream方法获得网络连接输入,同时返回一个IutputStream对象实例,。
. getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
2.如何开发一个Server-Client模型的程序
开发原理:
服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统 中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
***********************************************************************************
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @author Administrator
* 注意:困扰了很久,终于出来.
* System.in, System.out系统自带的输入输出流.
* Socket的输入输出流:当一方使用out.println()时候,另一方就可以自动in.readLine获得另一方的资源
* 即:在Socket两端:输入,输出是相对的.
*/
public class MyServer {
public MyServer(){
ServerSocket server=null;
Socket client=null;
BufferedReader in=null;
BufferedReader line=null;
PrintWriter out=null;
try{
//创建指定端口的服务器端套节字
server=new ServerSocket(10000);
System.out.println("创建服务器套节字成功! IP:"+server.getInetAddress()+" Port:"+server.getLocalPort());
/*
* 此方法用于侦听指定端口,
* 会产生阻塞.
* 直到客户端发送向此端口的建立Socket请求
* 请求成功,阻塞解除.
* 同时在服务器端创建一个随机端口的Socket
*/
client=server.accept();
System.out.println("创建客户端套节字成功! IP:"+client.getLocalAddress()+" Port:"+client.getPort()+" LocalPort:"+client.getLocalPort());
in=new BufferedReader(new InputStreamReader(System.in));
line=new BufferedReader(new InputStreamReader(client.getInputStream()));
out=new PrintWriter(client.getOutputStream());
boolean tag =false;
while(!tag){
String str=line.readLine();
System.out.println(str+" has revice form Client");
if(str!=null && str.equals("end")){
tag =true;
}
}
in.close();
line.close();
out.close();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String [] args){
new MyServer();
}
}**************************************************************************
客户:
**************************************************************************
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket; public class MyClient {
public MyClient(){
Socket client=null;
BufferedReader in=null;
BufferedReader line=null;
PrintWriter out=null;
try{
client=new Socket("127.0.0.1",10000);
System.out.println("创建客户端套节字成功! IP:"+client.getLocalAddress()+" Port:"+client.getPort()+" LocalPort:"+client.getLocalPort());
in=new BufferedReader(new InputStreamReader(System.in));
line=new BufferedReader(new InputStreamReader(client.getInputStream()));
out=new PrintWriter(client.getOutputStream());
boolean tag =false;
System.out.println("Hello! Input end to close this window!");
while(!tag){
String str=in.readLine();
System.out.print("Input: ");
out.println(str);
out.flush();
if(str!=null && str.equals("end")){
tag =true;
}
}
in.close();
line.close();
out.close();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String [] args){
new MyClient();
}
}************************************************************