网络编程

 网络编程的核心意义在于不同的电脑主机之间进行的数据交互,但是在Java中将这一概念又进一步进行了简化,即:Java是以JVM进程划分网络的(可能一台或多台电脑上会同时运行多个JVM,那么这些不同的JVM彼此都是一台主机),不同的JVM进程表示不同的主机

网络编程分类

        网络编程的实质意义在于数据的交互,而在这一交互过程之中一定就会分为服务器端与客户端,而这两端的开发就会存在有以下两种模式:

         Ø  形式一:C/S结构(Client / Server),此类模式的开发一般要编写两套程序,一套是客户端代码,另外一套属于服务器端代码。由于需要有编写程序,所以对于开发以及维护的成本较高。但是由于其使用的是自己的连接端口与交换协议,所以安全性比较高。而C/S结构程序的开发分为两种:TCP(传输控制协议,可靠的传输)、UDP(数据报协议)。

         Ø  形式二:B/S结构(Browser / Server),不再单独开发客户端代码,只开发一套服务器端程序,客户端将利用浏览器进行访问,这种模式只需要开发一套程序,但是安全性不高,因为使用的是公共的HTTP协议以及公共的80端口。

 

  java.net包提供了网络编程有关的开发工具类,在此包中有两个主要的核心操作类:

      ServerSocket类:是一个封装支持TCP协议的操作类,主要工作在服务器端,用于接收客户端请求;

      Socket类:也是一个封装了TCP协议的操作类,每一个Socket对象都表示一个客户端。

ServerSocket类的常用方法

No.

方法名称

类型

描述

1

public ServerSocket(int port) throws IOException

构造

开辟一个指定的端口监听,一般使用5000以上

2

public Socket accept() throws IOException

普通

服务器端接收客户端请求,通过Socket返回

3

public void close() throws IOException

普通

关闭服务器端

Socket类的常用方法

No.

方法名称

类型

描述

1

public Socket(String host, int port) throws UnknownHostException, IOException

构造

指定要连接的主机(IP地址)和端口

2

public OutputStream getOutputStream() throws IOException

普通

取得指定客户端的输出对象,使用的时候肯定使用PrintStream装饰操作

3

public InputStream getInputStream() throws IOException

普通

从指定的客户端读取数据,使用Scanner操作


客户端与服务器端交互

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

定义服务器端 —— 主要使用ServerSocket

import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class HelloServer {
	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(9999) ;// 所有的服务器必须有端口
		System.out.println("等待客户端连接........");// 提示信息
		Socket client = server.accept() ;	// 等待客户端连接
		// OutputStream并不方便进行内容的输出,所以利用打印流完成输出
		PrintStream out = new PrintStream(client.getOutputStream()) ;
		out.println("Hello World !");// 输出数据
		out.close(); 
		client.close();
		server.close();
	}
}

编写客户端 —— Socket

import java.net.Socket;
import java.util.Scanner;
public class HelloClient {
	public static void main(String[] args) throws Exception {
		Socket client = new Socket("localhost",9999) ;	// 连接服务器端
		// 取得客户端的输入数据流对象,表示接收服务器端的输出信息
		Scanner scan = new Scanner(client.getInputStream()) ;	// 接收服务器端回应数据
		scan.useDelimiter("\n") ;			// 设置分隔符
		if (scan.hasNext()) {		// 是否有数据
			System.out.println("【回应数据】" + scan.next());// 取出数据
		}
		scan.close();
		client.close();
	}
}

Echo程序

       在网络编程之中ECHO是一个经典的程序开发模型,本程序的意义在于:客户端随意输入信息并且将信息发送给服务器端,服务器端接收后前面加上一个“ECHO:”的前缀标记后将数据返还给客户端。在本程序中服务器端即要接收客户端发送来的数据,也要向客户端输出数据,同时考虑到需要进行多次数据交换,所以每次连接之后不应该立刻关闭服务器,而当用户输入了一些特定字符串(例如:“byebye”)后才表示可以结束本次的Echo操作。

实现服务器端

public class EchoServer {
	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(9999) ;// 定义连接端口
		Socket client = server.accept() ;	// 等待客户端连接
		// 得到客户端输入数据以及向客户端输出数据的对象,利用扫描流接收,打印流输出
		Scanner scan = new Scanner(client.getInputStream()) ;
		PrintStream out = new PrintStream(client.getOutputStream()) ;
		boolean flag = true ;	// 设置循环标记
		while(flag) {
			if (scan.hasNext()) {	// 是否有内容输入
				String str = scan.next().trim() ;// 得到客户端发送的内容,并删除空格
				if (str.equalsIgnoreCase("byebye")) {	// 程序结束标记
					out.println("拜拜,下次再会!");// 输出结束信息
					flag = false ;	// 退出循环
				} else {	// 回应输入信息
					out.println("ECHO : " + str);// 加“ECHO : ”前缀返回
				}
			}
		}
		server.close();
	}
}

定义客户端


public class EchoClient {
	public static void main(String[] args) throws Exception {
		Socket client = new Socket("localhost", 9999);		// 服务器地址与端口
		Scanner input = new Scanner(System.in); 			// 键盘输入数据
		// 利用Scanner包装客户端输入数据(服务器端输出),PrintStream包装客户端输出数据;
		Scanner scan = new Scanner(client.getInputStream());
		PrintStream out = new PrintStream(client.getOutputStream());
		input.useDelimiter("\n");	// 设置键盘输入分隔符
		scan.useDelimiter("\n");// 设置回应数据分隔符
		boolean flag = true;		// 循环标志
		while (flag) {
			System.out.print("请输入要发送数据:");
			if (input.hasNext()) {	// 键盘是否输入数据
				String str = input.next().trim();	// 取得键盘输入数据
				out.println(str); 	// 发送数据到服务器端
				if (str.equalsIgnoreCase("byebye")) {// 结束标记
					flag = false; // 结束循环
				}
				if (scan.hasNext()) {	// 服务器端有回应
					System.out.println(scan.next()); // 输出回应数据
				}
			}
		}
	}
}

建立线程处理

    在实际的开发中一个服务器需要同时处理多个客户端的请求操作,在这样的情况下就可以利用多线程来进行操作。把每一个连接到服务器端的客户都作为一个独立的线程对象保留












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值