浅谈Java 基于Socket和基于数据报的网络编程(二)
2.基于Socket的网络编程
2.1类
在java中,基于Socket的网络编程主要涉及两个类,一个是ServerSocket,另一个是Socket。它们都在java.net包中。
1.ServerSocket
ServerSocket实现服务器套接字。服务器套接字等待通过网络传入的请求。它基于该请求执行某些操作,然后向请求者返回结果。
(1)构造器:
public ServerSocket(int port) throws IOException。创建绑定到特定端口的套接字。参数可以是有效的端口号,也可以是0,0表示诗人任何空闲端口。
(2)常用方法:
public Socket accept() throws IOException。侦听并接收此套接字的连接,返回新的套接字,与请求者套接字建立连接。此方法在进行连接之前一直阻塞,一直监听。
2.Socket
实现客户端套接字。套接字是两台机器之间通信的端点。客户端呢通过套接字对象向服务器端发出请求。
(1)构造器:
public Socket(String host,int port) throws UnknownHostException,IOException。创建一个流套接字并将其连接到指定的主机之上的指定端口号。
(2)常用方法:
public InputStream getInputStream() throws IOException。返回此套接字的输入流。
public OutputStream getOutputStream() throws IOException。返回此套接字的输出流。
2.2服务器程序编写步骤
服务器程序能够接受客户端的请求,并能为客户端提供服务,提供服务的基础是与客户端进行数据传输。为了达到此目的,服务器程序就包含了一个最基本的部分,下面给出用Java编写最简单的服务器程序的步骤。
1.创建ServerSocket对象
ServerSocket ss=new ServerSocket(4321);
通过创建ServerSocket对象实现服务器端套接字,并指明提供服务的端口号是4321.客户端可以通过向这个端口号发出请求来申请服务。
2.等待客户连接
Socket s=ss.accept();
程序运行到此处处于等待状态,一直在侦听客户端端的请求,一旦接收到客户机的连接请求,则返回一个Socket对象,与请求者套接字建立连接。
3.生成输入输出流
InputStreamReader ins=new InputStreamReader(s.getInputStream());
BufferedReader in=new BufferedReader(ins);
PrintStream out=new PrintStream(s.getOutputStream());
由于套接字中的输入输出路都是字节流,为了传输方便,把输入输出流转换成带缓冲区的字符流,可以看到转换过程与标准输入的转换是一样的,这就是说一旦服务器端和客户端的连接建立以后,服务端的输入流与单机的标准输入流 知识数据源不同,前者的数据源是客户端,后者的数据源是键盘,但是对于输入流的操作都是一样的。同样的道理,把输出流转换成为PrintStream类型,就跟标准输出操作一样了,可以用方法print()以及println()想客户端输出数据了,这个操作与单机中向显示器输出是一样的。
4.处理输入输出操作
输入:in.readLine();
输出:out.println("Hi client!");
5.关闭输入输出流以及Socket
由于输入输出流是建立在连接上的,因此先关闭输入输出流,再关闭Socket连接。
in.close();
out.close();
s.close();
2.3 客户端程序编写步骤
客户端程序应该能向特定的端口发出请求信息,得到相应后,能与服务器程序进行数据传输。为了达到此目的,客户端程序也包含了一些最基本的部分,下面给出用Java编写最简单的客户端程序的步骤。
1.创建Socket对象
Socket s=new Socket("127.0.0.1",4321);
通过创建Socket对象,向特定端口发出请求,等待建立连接。本例中的服务器程序与客户端程序在同一台机器上运行的,因此,服务器的IP地址是127.0.0.1,由于前面服务器程序提供的端口是4321,所以客户端程序就向这个端口发出请求。
2.生成输入输出流
InputStreamReader ins=new InputStreamReader(s.getInputStream());
BufferedReader in=new BufferedReader(ins);
PrintStream out=new PrintStream(s.getOutStream());
生成输入输出流的方式与服务器程序中的一样。但是这里要清楚它们之间的关系。对于客户端的程序来说,它的输入流与服务器程序的输出流是一对,也就是说客户端程序的输入流的数据源是服务器程序的输出流。同样的道理。客户端的程序的输出流与服务器程序的输出流也是一对,客户端程序的输出流是服务器程序的输入流的数据源。
3.处理输入输出操作
输入:in.readLine();
输出:out.println();
与服务器端的输入输出操作一样。
4.关闭输入输出流及Socket
与服务器端的关闭操作一样。
import java.net.*;
import java.io.*;
/**
* 服务器类
* @author xx
*
*/
public class msa {
public static void main(String[] args) {
try{
ServerSocket ss=new ServerSocket(4321); //创建ServerSocket对象在4321端口提供服务
System.out.println("Server OK");
//因为服务器一般是一直运行的所以这里让其不断循环执行
while(true){
Socket s=ss.accept(); //监听客户端请求,一旦监听到就生成Socket对象,并奖励连接
//把套接字中的输入输入出字节流转换成字符流
InputStreamReader ins=new InputStreamReader(s.getInputStream());
BufferedReader in=new BufferedReader(ins); //服务端的输入流
String x=in.readLine(); //接收服务端输入流
System.out.println("INformation from client:"+x); //将客户端发来的信息输出到显示器
PrintStream out=new PrintStream(s.getOutputStream()); //服务器端的输出流
out.println("hello client!");
in.close(); //关闭输入流
out.close(); //关闭输出流
s.close(); //关闭Socket
}
}catch(IOException e){System.out.println(e.toString());}
}
}
import java.net.*;
import java.io.*;
/**
* 客户端
* @author xx
*
*/
public class mca {
public static void main(String[] args) {
try{
Socket s=new Socket("127.0.0.1",4321); //提供创建Socket对象向服务器的4321端口发出请求
PrintStream out=new PrintStream(s.getOutputStream()); //客户端的输出流
out.println("hello server"); //向服务器输出信息
InputStreamReader ins=new InputStreamReader(s.getInputStream());
BufferedReader in=new BufferedReader(ins); //客户端的输入流
String x=in.readLine();
System.out.println("Information from server:"+x); //将服务器传来的信息输出到显示器
out.close();
in.close();
s.close();
}catch(IOException e){}
}
}