在Java中使用Socket(套接字)来完成TCP程序的开发,使用此类可以方便的建立可靠的、双向的、持续的、点对点的通信连接。服务器端使用ServerSocket等待客户端的连接,,而每一个客户端都是用一个Socket对象表示。
1.ServerSocket类与Socket类
ServerSocket类主要运用在服务器端开发,用于接收客户端的连接请求。常用方法:
类型 方法 描述 构造方法 ServerSocket(int port)
创建绑定到特定端口的服务器套接字。 Socket
accept()
侦听并接受到此套接字的连接。 InetAddress
getInetAddress()
返回此服务器套接字的本地地址。 boolean
isClosed()
返回 ServerSocket 的关闭状态。 void
close()
关闭此套接字。 服务器端每次运行都要使用accept()方法等待客户端连接,此方法执行之后服务器端进入阻塞状态,直到客户端连接之后程序才向下继续执行。此方法返回Socket类型,每一个Socket都表示一个客户端对象。Socket常用方法:
类型 方法 描述 构造方法 Socket(String host, int port)
创建一个流套接字并将其连接到指定主机上的指定端口号。 InputStream
getInputStream()
返回此套接字的输入流。 OutputStream getOutputStream()
返回此套接字的输出流。 void close()
关闭此套接字。 boolean isClosed()
返回套接字的关闭状态。 在客户端,程序可以通过Socket类的getInputStream()方法取得服务器的输出信息;在服务器端,可以通过getOutputStream()方法取得客户端的输出信息。
2.服务器向客户端输出
服务器端程序:
package org.demo.net; import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; public class HelloServer { public static void main(String[] args) { ServerSocket server=null; Socket client=null; PrintStream out=null; try { server=new ServerSocket(8888); System.out.println("服务器运行,等待客户端连接"); client=server.accept(); String str="Hello!"; out=new PrintStream(client.getOutputStream()); out.println(str); out.close(); client.close(); server.close(); } catch (IOException e) { e.printStackTrace(); } } }运行结果:
客户端程序:
package org.demo.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException; public class HelloClient { public static void main(String[] args) { Socket client = null; try { client = new Socket("localhost",8888);//指定连接的主机和端口 BufferedReader buf = null;//声明BufferedReader对象,接受信息 //取得客户端的输入流 buf = new BufferedReader(new InputStreamReader(client.getInputStream())); String str = buf.readLine();//读取信息 System.out.println("服务器端输出内容:"+str); client.close(); buf.close(); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
此时客户端从服务器端将信息读取进来,完毕后,因为服务器端此时只能处理一次连接请求,所以也将关闭。
3.Echo程序
是网络编程通信交互的一个经典案例,称为回应程序,不同于之前的服务器端每次执行完毕后服务器都会退出,本程序应用循环的方式使用accept(),这样,每一个客户端执行完毕后服务器端都可以重新等待用户连接。
服务器端程序:
package org.demo.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; public class EchoServer { public static void main(String[] args) { ServerSocket server = null; Socket client = null; PrintStream out = null; BufferedReader buf = null; try { server = new ServerSocket(8888); boolean f = true; while(f){ System.out.println("服务器运行,等待客户端连接。"); client = server.accept(); //得到客户端的输入信息 buf = new BufferedReader(new InputStreamReader(client.getInputStream())); //实例化客户端的输出流 out = new PrintStream(client.getOutputStream()); boolean flag = true;//表示一个客户端是否操作完毕 while(flag){ String str = buf.readLine(); if(str == null || "".equals(str)){ flag = false; }else{ if("bye".equals(str)){ flag = false; }else{ out.println("ECHO:"+str);//向客户端回显信息 } } } out.close(); client.close(); } server.close(); } catch (IOException e) { e.printStackTrace(); } } }
运行结果:
客户端程序:
package org.demo.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; public class EchoClient { public static void main(String[] args) throws IOException { Socket client = null; client = new Socket("localhost",8888); BufferedReader buf = null; PrintStream out = null; BufferedReader input = null; //从键盘接收数据 input = new BufferedReader(new InputStreamReader(System.in)); out = new PrintStream(client.getOutputStream()); //从服务器端接收信息 buf = new BufferedReader(new InputStreamReader(client.getInputStream())); boolean flag = true; while(flag){ System.out.println("输入信息:"); String str = input.readLine();//从键盘接收信息 out.println(str);//向服务器输入信息 if("bye".equals(str)){ flag = false; }else{ String echo=buf.readLine();//接收ECHO信息 System.out.println(echo);//输出ECHO信息 } client.close(); buf.close(); } } }
运行结果:
4.服务器上的多线程
ExThread.java:
package org.demo.net; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class ExThread implements Runnable{ private Socket client = null; public ExThread(Socket client){ this.client = client; } public void run(){ PrintStream out = null; BufferedReader buf = null; try{ buf = new BufferedReader(new InputStreamReader (client.getInputStream())); out = new PrintStream(client.getOutputStream()); boolean flag = true; while(flag){ String str = buf.readLine(); if(str==null || "".equals(str)){ flag = false; }else{ if("bye".equals(str)){ flag = false; }else{ out.println("ECHO:"+str); } } } out.close(); client.close(); }catch(Exception e){ e.printStackTrace(); } } }主要功能是接收每一个客户端的Socket,并通过循环的方式接收客户端的输入信息及向客户端输出信息。
ExThreadServer.java:
package org.demo.net; import java.net.ServerSocket; import java.net.Socket; public class ExThreadServer { public static void main(String[] args) throws Exception{ ServerSocket server = null; Socket client = null; server = new ServerSocket(8888); boolean f = true; while(f){ System.out.println("服务器运行,等待客户端连接。"); client = server.accept(); new Thread(new ExThread(client)).start();//实例化并启动一个线程对象 } server.close(); } }
时间: 2024-11-05 11:35:12