计算机网络原理 实验2《Windows 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();
        }
    }
    

    }

此时,可以使用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();
        }
    }
}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值