java Tcp编程

来源:互联网 发布:qq飞车t3神谕天尊数据 编辑:程序博客网 时间:2024/06/06 03:31

java中和网络编程有关的基本API位于java.net包中,该包中包含了基本的网络编程实现,该包是网络编程的基础。

该包中既包含基础的网络编程类,也包含封装后的专门处理WEB相关的处理类。  

我们先简单了解一下,服务器跟客户端之间的联系;


Java语言中,对于TCP方式的网络编程提供了良好的支持,在实际实现时,以java.net.Socket类代表客户端连接,以java.net.ServerSocket类代表服务器端连接。在进行网络编程时,底层网络通讯的细节已经实现了比较高的封装,所以在程序员实际编程时,只需要指定IP地址和端口号码就可以建立连接了。

目标 1 :实现简单的服务端,客户端,服务端向客户端发送 “hello world”后关闭服务

首先实现服务端,借助于java.net.ServerSocket类

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[]) throws IOException{ServerSocket server = null;     //定义一个服务端Socket client = null;//定义一个客服端用来接受PrintStream out = null;  //定义一个打印输出流,向服务端发送信息的同时输出到屏幕,方便查看server = new ServerSocket(8090);//使用8090端口System.out.println("服务器运行,等待客户端链接。");client = server.accept();       //进入阻塞状态,服务端等待客服端的接入String str = "hello world";  out = new PrintStream(client.getOutputStream());  //得到客服端的输出流,实例化打印输入流out.println(str);//向客户端输出信息,并打印出来//关闭服务client.close();server.close();}}
接下来简单的看一下,java API中的ServerSocket类

构造方法摘要ServerSocket()
          创建非绑定服务器套接字。ServerSocket(int port)
          创建绑定到特定端口的服务器套接字。ServerSocket(int port, int backlog)
          利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。ServerSocket(int port, int backlog,InetAddress bindAddr)
          使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。

这里我们调用了第二个构造函数,指定了所用端口

accept()函数则等到客户端的接入

public Socket accept()              throws IOException
侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。

创建新套接字 s,如果存在安全管理器,则使用 s.getInetAddress().getHostAddress()s.getPort() 作为参数调用安全管理器的checkAccept 方法,以确保允许该操作。这可能会导致 SecurityException 异常。

客户端则比较简单

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[]) throws UnknownHostException, IOException{Socket client = null;       //定义一个客户端client = new Socket("localhost",8090);   //使用刚才定义的8090接口BufferedReader buf = null;//定义一个缓存输入流,用于一次接受信息buf = new BufferedReader(new InputStreamReader(client.getInputStream()));String str = buf.readLine();System.out.println("服务器输出内容:" + str);//关闭服务buf.close();client.close();}}
定义一个缓存输入流,连接上服务器后直接读取数据即可。

目标 2:实现Echo服务

客户端链接上服务器后,首先先服务器发送信息(一个字符串),服务器接受后在字符串前加上“Echo”并返回给客户端,客户端输出

实现Echo服务,服务器和客户端之间的链接同上,不同是服务要接受信息并加以处理;

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[]) throws IOException{ServerSocket server = null;Socket client = null;PrintStream out = null;BufferedReader buf = null;            //定义一个输入流,从客户端可到输入server = new ServerSocket(8090);while(true){System.out.println("服务器运行,等待客户端链接。");client = server.accept();//等待用户链接,进入阻塞状态out = new PrintStream(client.getOutputStream());//准备接受客户端的输入信息buf = new BufferedReader(new InputStreamReader(client.getInputStream()));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);}}}client.close();
}
}}

当客户端输入bye时则表示离开

以下是客户端的实现

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 UnknownHostException, IOException{Socket client = null;client = new Socket("localhost",8090);BufferedReader buf = null;       //定义一个缓冲输入流,一次性从服务端接受信息PrintStream out = null;//向服务端发送信息的输出流BufferedReader input = null;    //从系统读入字符串的输入流input = new BufferedReader(new InputStreamReader(System.in));buf = new BufferedReader(new InputStreamReader(client.getInputStream()));out = new PrintStream(client.getOutputStream());boolean flag = true;while(flag){System.out.println("输入信息");String str = input.readLine();   //从系统输入得到信息out.println(str);//将得到的信息发送给服务端if ("bye".equals(str)){flag = true;//当字符串为 bye 是终止输入}else{String echo = buf.readLine();//得到服务端返回的信息System.out.println(echo);}}buf.close();client.close();}}

不足:以上服务器的实现,虽然达到了我们的目的对客户端实现了交互,但是在同一时间内只能对一个客户端进行处理,也就是说当一个客户端正在跟服务器进行交互时,其他客户端是无法接入的。

目标 3:实现一个可多用户操作的服务器

要 实现一个多用户可同时操作的服务器,我们可以在服务器接受到一个客户端,对它开始处理时开启一个新的线程,交给一个新的线程去是实现我们的服务,什么意思呢

我们先来看 多线程服务器的实现

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 EchoThreadServer {public static void main(String args[]) throws IOException{ServerSocket server = null;Socket client = null;PrintStream out = null;BufferedReader buf = null;server = new ServerSocket(8090);while(true){System.out.println("服务器运行,等待客户端链接。");client = server.accept();//等待用户链接,进入阻塞状态new Thread(new EchoThread(client)).start();}
}}

这里我们通过启动new Thread(。。。)创建了一个新的线程,run()函数中则是对客户端信息处理的实现,对信息的处理同 目标 2;

import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.Socket;public class EchoThread implements Runnable {private Socket client = null;public EchoThread(Socket client) {this.client = client;}public void run() {PrintStream out = null;BufferedReader buf = null;try {out = new PrintStream(client.getOutputStream());// 准备接受客户端的输入信息buf = new BufferedReader(new InputStreamReader(client.getInputStream()));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);}}}client.close();} catch (Exception e) {System.out.println(e);}}}


0 0
原创粉丝点击