知识点:
网络编程的时代几乎已经结束了。
网络编程:
网络:是将物理上分开的主机进行连接所想成的交换区域。服务器端与客户端编程的开发操作实现。
实践工作中对于网络编程有两种形式:
形式一:C/S结构(Client/Server)此类模式的开发一般要些两套代码,一套服务器端代码,一套克服端代码。这样的程序开非常的麻烦,因为要维护两套程序的使用,因此程序的开发比较麻烦。但是比较安全,使用的是自己的连接端口,并且使用的是自己的通讯协议。
形式二:B/S结构(Browser/Server),不再单独开发客户端代码,只开 一套服务器程序。客户端将利用浏览器进行访问,但是其安全性不高,因为使用的都是HTTP协议以及公共的8080端口。
本次讲解的是CS程序,即:开发需要两套程序,并且这样的程序也可以称为Socket程序,而对于C/S结构程序分为两类。
TCP程序:是采用可靠的连接方式进行的传输。
UDP程序:不可靠的连接,属于数据报协议。
网络程序:TCP程序
服务器端类:ServerSocket,主要工作在服务器端,用于接受用户的请求.
客服端类:Socket,每一个连接到服务器上的用户都通过Socket表示。
范例:定义服务器端——主要使用ServerSocket
构造方法:public ServerSocket(int port,int backlog) throws IOException,设置监听端口;
接受客户端连接:public Socket accept()throws IOException
取得客户端输出功能,Socket类定义方法:
public InputStream getInputStream() throws IOException
代码:服务器端
package 网络编程;
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("等待客户端连接......");
//OutputStream并不方便进行内容输出,所以利用打印流完成输出
Socket client=server.accept();
PrintStream out=new PrintStream(client.getOutputStream());
out.println("Hello,World!");
out.close();
client.close();
server.close();
}
}
范例:编写客户端——Socket
构造方法:public Socket(String host,int port)throws UnknownHostException,IOException
—host表示主机的IP地址,如果本机直接访问那么localhost(172.0.0.1)代替IP。
得到输入数据:public InputStream getInputStream() throws IOException
代码:客户端
package 网络编程;
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.hasNextLine()){
System.out.println("回应数据"+scan.next());
}
scan.close();
client.close();
}
}
Echo程序:在网络编程之中ECHO是一个经典的程序开发,本程序的意义在于客户端随意输入信息,并且将信息发送给服务器端,服务器端接受后前面加一个“ECHO”的标记返回。
本序设计如下:
1.由于需要采用多次输入的形式,所以不能够每次连接后立刻关闭服务器端。
2.可以设置一个字符串,如果输入了“byebye”,那么才表示就结束本次的Echo操作。
范例:实现服务器端
package 网络编程;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
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(); //得到客户端发送的内容,trim()去掉左右空格
if(str.equalsIgnoreCase("byebye")){
out.println("拜拜,下次再会!");
flag=false; //推出循环
} else{ //应该回应输入信息
out.println("ECHO:"+str);
}
}
}
scan.close();
out.close();
client.close();
server.close();
}
}
范例:定义客户端
package 网络编程;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class EchoServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(9996);
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(); //得到客户端发送的内容,trim()去掉左右空格
if(str.equalsIgnoreCase("byebye")){
out.println("拜拜,下次再会!");
flag=false; //推出循环
} else{ //应该回应输入信息
out.println("ECHO:"+str);
}
}
}
scan.close();
out.close();
client.close();
server.close();
}
}
此时就实现了一个最简单的服务器端与客户端通讯。
此时的程序只能够连接一个客户端,而不能连接其他客户端,因为所有的操作都是在主线程上进行的开发,也就是说此时的程序是属于单线程的网络应用,而实际中不可能如此进行,所以为了能够让一个服务器端同时处理多个操作,使用多线程描述。把每一个连接到服务器的客户都作为一个独立的线程对象保留。
范例:
package 网络编程;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class EchoThread implements Runnable{
private Socket client;
public EchoThread(Socket client){
this.client=client;
}
@Override
public void run() {
try{
//得到客户的输入数据以及向客户输出数据对象
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(); //得到客户端发送的内容,trim()去掉左右空格
if(str.equalsIgnoreCase("byebye")){
out.println("拜拜,下次再会!");
flag=false; //退出循环
} else{ //应该回应输入信息
out.println("ECHO:"+str);
}
}
}
scan.close();
out.close();
client.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
package 网络编程;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class EchoServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(9996);
boolean flag = true;
while(flag){
Socket client =server.accept(); //连接客户端
new Thread(new EchoThread(client)).start();
}
server.close();
}
}
服务器开发的基础要素:网络支持类、IO、多线程