当前位置:   article > 正文

计算机网络原理 实验2《Windows Socket编程》_计算机网络实验二 socket通信编程与传输协议分析

计算机网络实验二 socket通信编程与传输协议分析
实验2《Windows Socket编程》
一、实验目的

通过实验,使学生熟悉并掌握计算机Windows 编程的基本知识,进一步加深学生对课堂所学基本内容的理解,掌握基本的Windows编程技巧,通过实验使得学生能够进行一些简单的网络程序设计。

二、实验内容
  1. 了解基本的Socket知识
  2. 基于java完成Socket编程,设计并实现一个简单的聊天系统,包括客户端及服务器端。
    2.1 完成服务端使用telnet与服务器通信
    2.2 完成客户端与服务端通信
    2.3 完成基于多线程的实现服务端可以与多个客户端通信
  3. 可选,重构现有代码完成带界面的软件。实现各客户端之间聊天,以及多人聊天室。
三、实验方法

实验方法为利用Intellij IDEA开发工具,JAVA编程语言实现,参考过往实验资料与网络资料之后自己实现完成。

四、实验步骤
  1. 开启本机的telnet服务,在终端输入telnet可进行连接,输入?可查看帮助信息。
    在这里插入图片描述
    在这里插入图片描述

  2. 打开Intellij IDEA开发工具进行项目程序编写;
    2.1 实现了一个简单的服务端: start函数负责建立服务端,等待连接,stop函数负责关闭连接以及相关的io流。Serversocket对象创建以后accept函数等待客户端连接。若没有客户端连接上,则会一直轮询,直到有客户端连接上,继续执行下面逻辑。当建立连接以后,双方建立通信管道,io流读取与写入数据。完成socket通信。

    //sampleServer.java
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;

    public class sampleServer {
    private ServerSocket serverSocket;
    private Socket clientSocket;
    private PrintWriter out;
    private BufferedReader in;

    //建立服务端,等待连接
    public void start(int port) throws Exception{
        serverSocket = new ServerSocket(port);
        clientSocket = serverSocket.accept();
        out = new PrintWriter(clientSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null){
            if(".".equals(inputLine)){
                out.println("good bye");
                stop();
                break;
            }else{
                out.println("server got msg: "+inputLine);
            }
        }
    }
    
    //关闭连接以及相关的io流
    public void stop() throws Exception{
        in.close();
        out.close();
        clientSocket.close();
        serverSocket.close();
    }
    
    public static void main(String[] args){
        try {
            sampleServer server = new sampleServer();
            server.start(23);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    }

此时,可以使用telnet连接,输入信息,即可发送给服务端。服务端接收到处理后返回。
在这里插入图片描述
在这里插入图片描述

2.2 完成客户端与服务端通信
在完成了可以使用telnet连接,并与之通信的服务器以后,我们编写自己的客户端代码与服务器进行通信。代码很简单。
StartConnection函数指定ip与端口,若与服务器成功建立连接,则获取建立的通道的io流,out与in输入输出流,来实现后续与服务端的消息接收与发送。
sendMessage函数基于io流发送消息。
StopConnection关闭与服务端的连接。
主函数获得用户在命令行的输入,发送给服务端。

//sampleClient.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class sampleClient {
    private Socket clientSocket;
    private PrintWriter out;
    private BufferedReader in;

    //指定ip和端口
    public void startConnection(String ip, int port)throws Exception{
        clientSocket = new Socket(ip, port);
        out = new PrintWriter(clientSocket.getOutputStream(),true);
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    }

    //基于IO流发消息
    public String sendMessage(String msg)throws Exception{
        out.println(msg);
        String resp = in.readLine();
        return resp;
    }

    //关闭与服务端的连接
    public void stopConnection(){
        try {
            in.close();
            out.close();
            clientSocket.close();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args){
        try{
            //bulid the connection
            sampleClient client = new sampleClient();
            client.startConnection("127.0.0.1",23);
            //recevice the input string from termnal and send it to server
            Scanner sc = new Scanner((System.in));
            while (true){
                String response = client.sendMessage(sc.nextLine());
                System.out.println(response);
                if(response.equals("good bye")){
                    client.stopConnection();
                    break;
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

2.3 完成基于多线程的实现服务端可以与多个客户端通信
完成以上实验,即可使用socket实现客户端与服务端之间的交互,进行简单的消息发送与接收。接下来我们可以实现多线程技术。
将上面服务器代码的获取io流,收发消息代码移植到clientHandler类中,该类继承自thread类。
修改start函数,依然是在本地的一个端口进行监听,但是我们这里使用一个循环来将每一个连接上来的client交给clientHandler来进行处理,这样主进程就不会阻塞,可以继续接收新客户端的连接,从而实现一个服务端连接多个客户端并与之通信的功能。
同时需要注意,我们使用一个clientList来维护所有的客户端。代码如下所示:

//clientList.java
import java.util.ArrayList;

public class clientList {
    public static ArrayList clientList;

    static {
        clientList = new ArrayList<multiServer.clientHandler>();
    }
}


//multiServer.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class multiServer {
    private ServerSocket serverSocket;

    public void start(int port)throws Exception{
        serverSocket = new ServerSocket(port);
        while (true){
            clientHandler client = new clientHandler(serverSocket.accept());
            clientList.clientList.add(client);
            client.start();
        }
    }

    public void stop() throws Exception{
        serverSocket.close();
    }

    public static class clientHandler extends Thread{
        private Socket clientSocket;
        private PrintWriter out;
        private BufferedReader in;

        public clientHandler(Socket socket){
            this.clientSocket = socket;
        }

        public void run(){
            try{
                out = new PrintWriter(clientSocket.getOutputStream(),true);
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                String inputLine;
                while ((inputLine = in.readLine()) != null){
                    if(".".equals(inputLine)){
                        out.println("good bye");
                        break;
                    }
                    out.println("msg from client" + clientList.clientList.indexOf(this) + "--msg:" + inputLine);
                }
                in.close();
                out.close();
                clientSocket.close();
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }
}


//main.java
public class main {
    public static void main(String[] args){
        try{
            new multiServer().start(23);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
五、实验结果

实验运行步骤及结果如下所示:

  1. 在Intellij IDEA中运行main函数;
  2. 运行命令行,输入telnet,连接telnet服务,再输入o,输入连接主机 localhost;
    在这里插入图片描述
  3. 接下来便可以运行第一个客户端,客户端即可输入信息,服务端可以反馈;
    在这里插入图片描述
  4. 重复第二步第三步即可开启多个客户端;
    在这里插入图片描述
    在这里插入图片描述
六、实验小结

本次实验是要是了解socket编程知识,客户端与服务端的交互,多阅读相关资料熟悉实验中需使用的方法就会轻松很多。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/172080
推荐阅读
相关标签
  

闽ICP备14008679号