C/S程序:表示的客户/服务器程序,每次需要编写两套程序
|- MSN、QQ:一般会有两套程序,一个是服务器端,另外一个是客户端
B/S程序:表示的浏览器/ 服务器,可以理解为动态WEB,论坛
本季目标
[零基础学JAVA]Java SE应用部分-32.Java网络编程_JAVA
Sock:TCP通讯
数据报:UDP通讯
Socket程序需要的类:
1、所有的用户对于服务器来讲都是一个Socket客户端。
2、在服务器上使用ServerSocket类接收客户端的Socket
Socket通信模型
[零基础学JAVA]Java SE应用部分-32.Java网络编程_TCP_02
Socket编程的四个基本步骤
[零基础学JAVA]Java SE应用部分-32.Java网络编程_JAVA_03
编写一个服务器程序:ServerSocket
[零基础学JAVA]Java SE应用部分-32.Java网络编程_网络编程_04
只要是网络连接都要求有一个端口
public ServerSocket(int port)
public Socket accept() throws IOException
通过此方法等待客户端的socket进行访问。
ServerSocket01服务器端代码:
[零基础学JAVA]Java SE应用部分-32.Java网络编程_UDP_05
此服务器端的功能非常的简单,就是接收客户端的请求,之后在屏幕上输出哈~
[零基础学JAVA]Java SE应用部分-32.Java网络编程_JAVA_06
Windows中有一个telnet命令,通过此命令就可以直接连接到服务器了。
[零基础学JAVA]Java SE应用部分-32.Java网络编程_JAVA_07
客户端收到http://redking.blog.51cto.com字符串,同时服务器端显示“客户端回应完毕~~~”
[零基础学JAVA]Java SE应用部分-32.Java网络编程_网络编程_08
只要是符合网络的协议标准,所有的客户端都可以连接到此服务器端上。
但是一般情况下,很少说直接去使用telnet连接,往往会编写一个客户端。
Socket
public Socket(String host,int port) throws UnknownHostException,IOException
指定一个主机的IP地址和一个端口
ClientSocket01客户端代码:
[零基础学JAVA]Java SE应用部分-32.Java网络编程_网络编程_09
验证下效果,和telnet一样哈~
[零基础学JAVA]Java SE应用部分-32.Java网络编程_UDP_10
以上代码验证了,程序需要编写两套程序:
· 一个是服务器端
· 另外一个是客户端
现在发现所有的代码只是执行一次就完了,那么能不能说执行多次呢?由我的用户可以自己发出中断的指令。
这样的做法我们可以做一个Socket经典 —— Echo程序
用户发什么内容,服务器就会回应什么内容:
EchoServer代码:
import java.io.*;    
import java.net.*;    
public class EchoServer{    
        //此处为了省去处理try...catch直接抛出了异常    
        public static void main(String args[]) throws Exception{    
                ServerSocket server = null;    
                //输出肯定使用打印流    
                PrintStream out = null;    
                //服务器肯定也要接收输入    
                BufferedReader buf = null;    
                //1.实例化一个服务器的监听端    
                server = new ServerSocket(9999);    
                //可以使用一种死循环的方式接收内容    
                Socket client = null;    
                while (true){    
                        //不断接收内容    
                        client = server.accept();    
                        //准备好向客户端输出内容    
                        out = new PrintStream(client.getOutputStream());    
                        //而且客户端要有输入给服务器端    
                        buf = new BufferedReader(new InputStreamReader(client.getInputStream()));    
                        //下面先给出一个完整的信息提示    
                        out.println("您好!欢迎光临:http://redking.blog.51cto.com");    
                        out.println("输入bye表示退出哈~");    
                        //一个用户要发很多的信息    
                        while (true){    
                                //接收客户端发送而来的内容    
                                String str = buf.readLine();    
                                if (str==null){    
                                        //如果str为空就表示退出    
                                        break;    
                                }else{    
                                        //如果输入的是bye则表示系统退出    
                                        if ("bye".equals(str)){    
                                                break;    
                                        }    
                                        //可以对用户发来的信息进行回应    
                                        out.println("ECHO:"+str);    
                                }    
                        }    
                        //进行收尾工作    
                        out.close();    
                        buf.close();    
                        client.close();    
                        //如果要关闭服务器时可以设置标志    
                        //server.close();    
                }    
        }    
}
看下效果:
[零基础学JAVA]Java SE应用部分-32.Java网络编程_UDP_11
现在我们用telnet连接上去看下效果
[零基础学JAVA]Java SE应用部分-32.Java网络编程_UDP_12
输入bye退出连接
[零基础学JAVA]Java SE应用部分-32.Java网络编程_TCP_13
同时可以多次连接
[零基础学JAVA]Java SE应用部分-32.Java网络编程_零基础学JAVA_14
典型的包含了输入和输出
EchoClient代码:
import java.io.*;    
import java.net.*;    
public class EchoClient{    
        public static void main(String args[]) throws Exception{    
                Socket client = null;    
                BufferedReader buf = null;    
                PrintStream out = null;    
                //1.连接服务器    
                client = new Socket("localhost",9999);    
                //接收服务器端的输入信息    
                buf = new BufferedReader(new InputStreamReader(client.getInputStream()));    
                System.out.println(buf.readLine());    
                System.out.println(buf.readLine());    
                //之后准备从键盘接收数据    
                BufferedReader in = new BufferedReader(new InputStreamReader(System.in));    
                String userInput = null;    
                out = new PrintStream(client.getOutputStream());    
                while ((userInput=in.readLine())!=null){    
                        //表示有内容进来,要把内容发送到客户端    
                        out.println(userInput);    
                        //接收服务器端的回应    
                        System.out.println(buf.readLine());    
                }    
                out.close();    
                in.close();    
                client.close();    
        }    
}
[零基础学JAVA]Java SE应用部分-32.Java网络编程_TCP_15
但是此程序有一个问题,即:当一个用户操作的时候,其他用户是不能操作的
程序是单线程的,所以每次只能一个用户访问。
此处如果想解决,则只能使用多线程进行操作。
首先需要编写一个线程的类:
ThreadServer代码:
import java.io.*;    
import java.net.*;    
public class ThreadServer implements Runnable{    
        //现在所有的Socket都要归入到一个线程之中    
        private Socket client = null;    
        public ThreadServer(Socket client){    
                this.client = client;    
        }    
        public void run(){    
                //要不断的接收客户发送来的信息    
                String input = null;    
                //通过BufferedReader进行接收    
                BufferedReader buf = null;    
                //有一个输出的对象    
                PrintStream out = null;    
                try{    
                        buf = new BufferedReader(new InputStreamReader(this.client.getInputStream()));    
                        while(true){    
                                //接收发送过来的信息    
                                input = buf.readLine();    
                                out = new PrintStream(this.client.getOutputStream());    
                                if ("bye".equals(input)){    
                                        break;    
                                }else{    
                                        out.println("ECHO:"+input);    
                                }    
                        }    
                        this.client.close();    
                }catch (Exception e){}    
        }    
}
EchoServer01服务器端代码: 
import java.io.*;    
import java.net.*;    
public class EchoServer01{    
        //此处为了省去处理try...catch直接抛出了异常    
        public static void main(String args[]) throws Exception{    
                ServerSocket server = null;    
                //输出肯定使用打印流    
                PrintStream out = null;    
                //服务器肯定也要接收输入    
                BufferedReader buf = null;    
                //1.实例化一个服务器的监听端    
                server = new ServerSocket(9999);    
                //可以使用一种死循环的方式接收内容    
                Socket client = null;    
                while (true){    
                        //不断接收内容    
                        client = server.accept();    
                        //在此处启动了一个线程    
                        new Thread(new ThreadServer(client)).start();    
                }    
        }    
}
使用telnet测试效果哈~
[零基础学JAVA]Java SE应用部分-32.Java网络编程_UDP_16 
通过以上代码,可以发现,多线程实际上在服务器上是比较常用的。
服务器 = 多线程 + IO + Socket
Socket程序实际上是属于TCP程序,是一个稳定的连接
 
UDP程序:数据报程序
[零基础学JAVA]Java SE应用部分-32.Java网络编程_JAVA_17
Send发送端代码:
import java.io.*;    
import java.net.*;    
public class Send{    
        public static void main(String args[]) throws Exception{    
                DatagramSocket ds = null;    
                DatagramPacket dp = null;    
                //发送端必须有一个监视的端口    
                ds = new DatagramSocket(9999);    
                String str = "http://redking.blog.51cto.com";    
                //发送的内容只能是byte数组    
                //接收端端口号是8888    
                dp = new DatagramPacket(str.getBytes(),str.length(),InetAddress.getByName("localhost"),8888);    
                ds.send(dp);    
                ds.close();    
        }    
}
看下效果:
[零基础学JAVA]Java SE应用部分-32.Java网络编程_网络编程_18
信息已经发送出去了哈~
下面我们再写个接收代码
[零基础学JAVA]Java SE应用部分-32.Java网络编程_TCP_19
Receive接收端代码:
import java.io.*;    
import java.net.*;    
public class Receive{    
        public static void main(String args[]) throws Exception{    
                DatagramSocket ds = null;    
                DatagramPacket dp = null;    
                //要有一个空间大小    
                byte b[] = new byte[1024];    
                //ds的监听端口就表示发送端指定好的    
                ds = new DatagramSocket(8888);    
                dp = new DatagramPacket(b,b.length);    
                //开始接收    
                ds.receive(dp);    
                System.out.println(new String(dp.getData()).trim());    
                ds.close();    
        }    
}
现在我们测试一下哈~首先必须接收端开启着
[零基础学JAVA]Java SE应用部分-32.Java网络编程_UDP_20
然后我们运行发送端发送信息
[零基础学JAVA]Java SE应用部分-32.Java网络编程_网络编程_21
总结
网络编程在实际中确实使用越来越少,JAVA的主要特点全部集中在了JAVA WEB上了。
只需要了解以下概念即可:
· 网络程序的分类:TCP、UDP
· 服务器 = IO + Socket + Thread
###################################################