TCP 程序设计

在java中使用Socket (即套接字)完成TCP程序的开发,使用此类可以方便的建立可靠的、双向的、持续的、点对点的通信连接。

在Socket的程序开发中,服务器端使用ServerSocket 等待客户端的连接,对于java的网络程序来讲,每一个客户端都使用一个Socket 对象表示,通过accept() 方法进行连接。


一:ServerSocket 类 与 Socket 类

1、用法及实现范例

ServerSocket类主要用在服务器端程序的开发商,用于接收客户端的连接请求,在服务器端每次运行时都要使用accept() 方法等待客户端连接,此方法执行之后,服务器端将进入阻塞状态,直到客户端连接之后程序才可以向下继续执行。此方法返回值类型是 Socket ,每一个 Socket 都表示一个客户端对象。

在客户端,程序可以通过 Socket 类的 getInputStream() 方法取得服务器的输出信息,在服务器端可以通过 getOutputStream() 方法取得客户端的输出信息。

范例1:

package haizhu.com.socket;

import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketDemo01 {
	public static void main(String[] args) throws Exception{
		String str = "Hello world !";

		ServerSocket server = null;						// 声明ServerSocket对象
		Socket client = null;							// 一个Socket 对象表示一个客户端
		PrintStream out = null;							// 声明打印流对象,以向客户端输出
		server = new ServerSocket(8888);				// 此时服务器在8888端口等待客户端的访问
		System.out.println("服务器运行,等待客户端连接。");
		client = server.accept();						// 程序阻塞,等待客户端的连接
		out = new PrintStream(client.getOutputStream());//实例化打印流对象,输出信息
		out.println(str);								// 输出信息
		out.close();									// 关闭打印流
		client.close();									// 关闭客户端连接
		server.close();									// 关闭服务器连接
	}
}
package haizhu.com.socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

public class ClientSocketDemo01 {
	public static void main(String[] args) throws Exception{
		Socket client = null;						// 声明Socket对象
		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();								// 关闭Socket
		buf.close();								// 不安比输入流
	}
}

ServerSocketDemo01 执行到 accept() 方法后,程序进入到阻塞状态,此阻塞状态会在客户端连接之后改变。运行ClentSocketDemo01 之后,第一个方法才继续运行,然后打印出 str 结束。

上面程序的主要结构是:服务器端启动ServerSocket,启动创建客户端Socket对象,并使用getInputStream 接收内容。等待调用这个Socket对象并调用getOutputStream方法打印出接收的内容。

2、Echo程序

这是网络编程通信交互的一个经典案例,称为回应程序,即客户端输入哪些内容,服务器端会在这些内容前加上“ECHO:”并将信息发回客户端,下面就完成这样的一个程序。

上面的程序,服务端每次执行完毕后服务器都会退出,这是因为服务器端只能接收一个客户端的连接,主要是由于accept() 方法只能使用一次。本程序中将通过循环的方式使用accept() ,这样,每一个客户端执行完毕后,服务器端都可以重新等待用户连接。

范例2:

package haizhu.com.socket;

import java.io.BufferedReader;
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 Exception{
		ServerSocket server = null;
		Socket client = null;
		PrintStream out = null;
		BufferedReader buf = null;
		server = new ServerSocket(8888);
		Boolean t = true;
		while(t){
			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();
	}
}
package haizhu.com.socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class EchoClient {
	public static void main(String[] args) throws Exception{
		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();
				System.out.println(echo);
			}
		}
		client.close();
		buf.close();
		
	}
}

3、多线程网络编程

上面的例子虽然能够接收多条信息,但是一次只能连接一个客户端,要想连接多个客户端,就需要使用多线程:

范例3:

package haizhu.com.socket;

import java.net.ServerSocket;
import java.net.Socket;

public class EchoServerThread {
	public static void main(String[] args) throws Exception{
		ServerSocket server = null;
		Socket client = null;
		server = new ServerSocket(8888);
		Boolean t = true;
		while(t){
			System.out.println("服务器正在运行,等待客户端连接。");
			client = server.accept();
			new Thread(new EchoClientThread(client)).start();
		}
		server.close();
	}
}
package haizhu.com.socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class EchoClientThread implements Runnable{
		private Socket client = null;
		public EchoClientThread(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();
			}
		}
	}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值