2016-11-06 网络编程

如果要进行网络编程最为核心的就是两个类:

      |-服务器类:ServerSocket,主要工作在服务器端,用于接收用户的请求。

      |-客户端类:Socket,每一个连接到服务器上的用户都通过Socket表示。

一、服务器端

      (1)构造方法:public ServerSocket(int port) throws IOException(设置监听的接口);

      (2)接收客户端连接:public Socket accpet()throws IOException;

      (3)取得客户端的输出功能,Socket类定义方法:public OutputStream getOutputStream() throws IOException

      服务器端代码:此时服务器中只是输出一个字符串“Hello World”;

package cn.mldn.demo14;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestDemo {
    public static void main(String[] args) throws Exception {
        // 所有服务器必须要设置端口号,这里设置端口号9999
        ServerSocket server = new ServerSocket(9999);
        System.out.println("等待客户端连接....");
        //等待客户端连接
         Socket client = server.accept();
        PrintStream out = new PrintStream(client.getOutputStream());
        out.println("Hello World");
        out.close();
        client.close();
        server.close();
    }
}

二、客户端

      (1)构造方法:public Socket(String host,int port) throws UnknownHostException,IOException;

            |-host表示主机的IP地址,如果访问的是本机那么使用localhost代替IP

       (2)得到输入的数据:public InputStream getInputStream()throws IOException

        客户端代码:

package cn.mldn.demo14;
import java.net.Socket;
import java.util.Scanner;
public class TestDemo01 {
    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();
    }
}

      测试结果: 在DOS下进行验证:

 QQ20161106185633_thumb7

三、Echo程序

      上面的代码客户端连接服务器只能连接一次,并且接收输入数据输出后结束。

      Echo程序:客户端随意的输入信息并且将信息发送给服务器端,服务器接收后,前面加上一个“ECHO:”标记返回;

      范例程序:

          |-由于采用多次输入的形式,多以不能够每次连接之后就断开服务器;

          |-可以设置一个字符串,如果输入的结果是“byebye”,那么才表示结束Echo操作;

      服务器端代码:

package cn.mldn.demo15;
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(10000);
       System.out.println("等待客户端连接....");
       //连接客户端
        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);
                }
            }
        }
        scan.close();
        out.close();
        client.close();
        server.close();
    }
}

      客户端代码:

package cn.mldn.demo15;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class EchoClient {
    public static void main(String[] args) throws Exception{
        Socket client = new Socket("169.254.77.143",10000);
        //键盘输入数据
         Scanner input = new Scanner(System.in);
        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.println("请输入要发送的数据:");
            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());
                }
            }
        }
        input.close();
        scan.close();
        out.close();
        client.close();
    }
}

      测试结果: 在DOS下进行验证:

QQ20161106193448_thumb5

      此时上面的代码也会存在一个问题:此时的服务器只能接收一个客户端运行,因为所有的操作流程全部在主线程下运行,因此如果想解决这个问题,就必须要引出多线程的操作模式。把每一个连接的服务器端的客户端都当成是一个独立的线程操作。因此需要修改服务器端的代码;

package cn.mldn.demo15;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
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();//得到客户端发送的内容
                    if(str.equalsIgnoreCase("byebye")){//程序结束标志
                        out.println("拜拜,下次再会!");
                        flag = false;//退出循环
                    }else{//应该回应输出的信息
                        out.println("Echo:"+str);
                    }
                }
            }
        scan.close();
        out.close();
        client.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
public class EchoServer{
    public static void main(String[] args) throws Exception{
        ServerSocket server = new ServerSocket(10000);
        boolean flag = true;
        while(flag){
            Socket client = server.accept();//连接客户端
            new Thread(new EchoThread(client)).start();
        }
        server.close();
    }
}

       测试结果: 在DOS下进行验证:

QQ20161106195518_thumb1

      客户端与服务器之间的开发要素:网络支持类,I/O类,多线程

posted on 2016-11-06 20:10  G-X  阅读(189)  评论(0)    收藏  举报