`
dpr905ds
  • 浏览: 18994 次
社区版块
存档分类
最新评论

java socket连接c/s (转)

 
阅读更多

java socket连接c/s (转)
2010年07月08日
  用java实现的简单Server/Client文件传输关键字: java server client
  用一种编程语言实现一个简单的Server/Client程序; 该程序的主要功能是利用Client从Server端下载一个文件; 在下载之前,需要有一定的用户身份验证机制(说白了就是先输入以下用户名和密码); Server应该是多线程机制的,即为每个Client请求Server都要有一个线程去处理,而不是所有的Client都是一个Server线程处理。 ok,这就是需求,单从编程角度来讲,题目不难,单老师说过一句话,我觉得非常有道理,“看一万个程序,不如自己亲自写一个程序,写一万个程序,不如努力写一个好程序”,所以我就利用十一假期的最后两天,完成了这样一个作业,当然大部分时间还是画在了学习不太熟悉的python上。在这里,还要感谢一下CSDN上“wumingabc的专栏”的一篇blog,参考了他的一些代码。
  处理流程:
  server启动,监听client请求; client启动; server监听到client,发送“Hi”; client收到“Hi” client要求用户输入用户名; 用户输入用户名(如yangsq),发送到服务器(形式为“username:yangsq”); 服务器验证是否存在这样一个用户,如果有到step 8,否则转到5; client用求用户输入密码(如123456),发送到服务器(形式为“password:123456”); 服务器验证密码是否正确,不正确转到step 8,正确开始传输文件(为了简单,文件预先指定好); client收到文件,结束后发送“bye”;同时server端收到“bye”后结束线程。 服务器端:
  java 代码
  import java.io.BufferedOutputStream;    import java.io.BufferedReader;    import java.io.BufferedWriter;    import java.io.DataOutputStream;    import java.io.File;    import java.io.FileInputStream;    import java.io.IOException;    import java.io.InputStream;    import java.io.InputStreamReader;    import java.io.OutputStream;    import java.io.OutputStreamWriter;    import java.io.PrintWriter;    import java.net.ServerSocket;    import java.net.Socket;    import java.util.HashMap;    import java.util.Map;       public class SimpleServer extends Thread{        private static final int DEFAULT_PORT = 4444;        private static final String DEFAULT_FILE_NAME = "PyNet.pdf";        private Socket socket;                public SimpleServer(Socket socket){            this.socket = socket;            start();        }                @Override       public void run() {            System.out.println("Connected from " + socket.getRemoteSocketAddress());            try {                BufferedReader in = new BufferedReader(                        new InputStreamReader(socket.getInputStream()));                PrintWriter out = new PrintWriter(                        new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);                String inputLine, outputLine;                                HandleInput handleInput = new HandleInput();                outputLine = handleInput.handle(null);                out.println(outputLine);                                while((inputLine = in.readLine()) != null){                    outputLine = handleInput.handle(inputLine);                    out.println(outputLine);                    out.flush();                    if(outputLine.equals("bye"))                        break;                    if(outputLine.equals("password:valid")){                        //prepare for the transmission of the file                        Thread.sleep(2000);                        InputStream fileInput = new FileInputStream(new File(DEFAULT_FILE_NAME));                        OutputStream fileOutput = new DataOutputStream(                                new BufferedOutputStream(socket.getOutputStream()));                        byte[] buf = new byte[2048];                                                //transmit the file                        int num = fileInput.read(buf);                        while(num != -1){                            fileOutput.write(buf, 0, num);                            fileOutput.flush();                            num = fileInput.read(buf);                        }                                                fileInput.close();                        fileOutput.close();                    }                }                                in.close();                out.close();                System.out.println("Disconnected from " + socket.getRemoteSocketAddress());                socket.close();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }                private class HandleInput{            private  Map userInfo = new HashMap();            private String username = "";            private String password = "";                        public HandleInput(){                userInfo.put("yangsq", "yangsq");                userInfo.put("abc", "abc");                userInfo.put("123", "123");            }                        public String handle(String input){                String output = "";                if(input == null)                    output = "Hi";                else if(input.startsWith("username")){                    username = input.split(":")[1];                    if(userInfo.containsKey(username))                        output = "username:valid";                    else                       output = "username:invalid";                }else if(input.startsWith("password")){                    password = input.split(":")[1];                    if(userInfo.get(username).equals(password))                        output = "password:valid";                    else                       output = "password:invalid";                }else if(input.equals("bye")){                    output = "bye";                }                return output;            }        }           public static void main(String[] args) {                        int port = DEFAULT_PORT;                        if(args.length > 0){                port = Integer.parseInt(args[0]);            }                        try {                ServerSocket serverSocket = new ServerSocket(port);                System.out.println("Server Started");                try {                    while(true){                        Socket theSocket = serverSocket.accept();                        try {                            new SimpleServer(theSocket);                        } catch (Exception e) {                            e.printStackTrace();                            theSocket.close();                        }                    }                } catch (Exception e) {                    // TODO: handle exception                    e.printStackTrace();                } finally {                    if(serverSocket != null)                        serverSocket.close();                }            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }  
  说明:
  main函数是Server的启动点,在这里我们建立了一个ServerSocket的实例,这个类是java中专门进行Server端编程的,它可以进行很多的复杂配置,这里知识把它建立在了一个端口之上(line-125),然后为请求返回socket(line-131)。 SimpleServer类继承了Thread,也就是说,我的想法是为每一个Client请求,都有一个SimpleServer去处理。这是怎样实现的呢?看line-128到line-136,这里ServerSocket的实例在端口4444进行监听,只要有一个请求,就new一个SimpleServer去处理(如果没有请求,程序就会阻塞在ServerSocket的accept方法上line-129) 既然SimpleServer继承了Thread,那么它的最重要的方法就是run(line-29),可以看到,在new SimpleServer的时候就启动了它的run方法。 SimpleServer的主要处理流程在line-42到line-67,为了更清晰,把其中的用户身份验证提出来组成一个内部类HandleInput。 负责文件传输的是line-48到line-66,也即clien的密码正确后开始。这里需要说明的是流的实现,与用户交互的时候我们用的是New IO,他们是面向字节(1字节=2byte)的,这很合适,因为我们的用户信息都是字节的(简单的说就是面向asc字符的),所以这里我们就用了readline和println方法(这两个都是Reader和Writer的方法);但是我们要传输的是一个二进制文件(说白了就是面向byte的),所以用New IO就不合适了,所以转向了InputStream(读入文件)和OutputStream(把文件通过socket写出)。 客户端:
  java 代码
  import java.io.BufferedInputStream;    import java.io.BufferedReader;    import java.io.DataInputStream;    import java.io.File;    import java.io.IOException;    import java.io.InputStream;    import java.io.InputStreamReader;    import java.io.PrintWriter;    import java.io.RandomAccessFile;    import java.net.Socket;    import java.net.UnknownHostException;       public class SimpleClient {        private static final int DEFAULT_PORT = 4444;        private static final String DEFAULT_HOST = "localhost";                public static void main(String[] args) {            String host = DEFAULT_HOST;            int port = DEFAULT_PORT;                        if(args.length > 0){                host = args[0];            }                        if(args.length >1 ){                port = Integer.parseInt(args[1]);            }                        Socket theSocket = null;            PrintWriter out = null;            BufferedReader in = null, userIn = null;                        try {                theSocket = new Socket(host, port);                                in = new BufferedReader(                        new InputStreamReader(theSocket.getInputStream()));                out = new PrintWriter(theSocket.getOutputStream());                userIn = new BufferedReader(                        new InputStreamReader(System.in));                                System.out.println("Connected to the simple file server");                String fromUser, fromServer;                                while((fromServer = in.readLine()) != null){                    if(fromServer.equals("bye"))                        break;                    else if(fromServer.equals("Hi")){                        System.out.println("Do you want to get the 'PyNet.pdf' file?(y/n):");                        fromUser = userIn.readLine();                        if(fromUser.equals("y")){                            System.out.println("Please input your username:");                            fromUser = userIn.readLine();                            out.println("username:" + fromUser);                            out.flush();//notice: if this sentence is lost, the info will not arrive at server side                        }else                           break;                    }else if(fromServer.startsWith("username")){                        if(fromServer.split(":")[1].equals("valid")){                            System.out.println("Please input your password:");                            fromUser = userIn.readLine();                            out.println("password:" + fromUser);                            out.flush();                        }else{                            System.out.println("Please input your username:");                            fromUser = userIn.readLine();                            out.println("username:" + fromUser);                            out.flush();                        }                    }else if(fromServer.startsWith("password")){                        if(fromServer.split(":")[1].equals("valid")){                            System.out.println("Downloading...");                                                        //prepare for the receiving                            File newFile = new File("new.pdf");                            newFile.createNewFile();                            RandomAccessFile raf = new RandomAccessFile(newFile, "rw");                                                        InputStream fileInput = new DataInputStream(                                    new BufferedInputStream(theSocket.getInputStream()));                            byte[] buf = new byte[2048];                                                        //receiving                            int num = fileInput.read(buf);                            while(num != -1){                                raf.write(buf, 0, num);                                raf.skipBytes(num);                                num = fileInput.read(buf);                            }                                                        in.close();                            raf.close();                            System.out.println("File download is finished");                            break;                        }else{                            System.out.println("Please input your password:");                            fromUser = userIn.readLine();                            out.println("password:" + fromUser);                            out.flush();                        }                    }                }                                out.println("bye");                out.flush();                                out.close();                in.close();                userIn.close();                theSocket.close();            } catch (UnknownHostException e) {                // TODO Auto-generated catch block                e.printStackTrace();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }   
  这个比较简单,除了用户交互外,最核心的就是line-71到line-94这段处理文件下载的了,当SimpleClient收到服务器的“password:valid"就表示用户身份验证通过,可以执行文件下载了。这部分也是混合使用了New IO和Old IO,原因和上边解释的一样。
  这里还要强调一点的是在网络编程的时候,println以后,一定要flush以下。为什么呢?学过网络的人都知道,当一个package太小是,网络并不会把它发出去,而是等到足够大时。我在实际测试时,就忘记了在println后写flush,结果这边明明已经out出了,但Server端就是在那塞着,这个问题困扰了我半天,呵呵。
分享到:
评论

相关推荐

    大二Java课程作业,基于Java Socket的C/S架构IM

    实现了C/S架构的Socket多线程IO通信。 实现了Socket长连接的TCP网络通信。 基于Java GUI的人机交互界面,单个服务器(Server)持续处理客户端信息并统一转发,多个客户端(Client)可以同时持续与服务器建立连接并相互...

    C/S聊天程序(JAVA,C/S)

    - `Client.java`:客户端的主程序,包含用户界面和Socket连接代码。 - `ChatServerThread.java`:服务器端处理每个客户端连接的线程类。 - `ChatClient.java`:客户端的聊天逻辑,包括发送和接收消息。 - `GUI.java`...

    利用Java Sock实现C/S通信

    下面将详细介绍Java Socket在C/S通信中的应用,以及如何构建这样的系统。 一、Java Socket基础 1. Socket概念:Socket在计算机网络中是一种进程间通信机制,它提供了一种在网络上的两个进程之间建立和维护连接的...

    基于SOCKET的C/S结构聊天室

    在这个基于Java的聊天室项目中,我们利用了Socket编程来实现C/S架构,从而实现用户之间的实时交互。 Socket是TCP/IP协议族的一部分,它提供了进程间的网络通信能力。在C/S结构中,服务器端(Server)通常负责监听...

    java版C/S简单socket通讯

    Java版的C/S简单Socket通讯是基于Java编程语言,利用Socket接口实现的客户端/服务器通信模型。在这个场景中,"SWT"(Standard Widget Toolkit)是用于构建图形用户界面(GUI)的库,它提供了丰富的控件和组件,使得...

    java课程设计c/s结构的图书管理系统

    6. **网络编程**:在C/S架构中,客户端和服务器之间的通信涉及到网络编程,Java的Socket编程接口(如TCP/IP)可能被用到。 7. **MVC设计模式**:Model-View-Controller模式是Java Web开发中常见的设计模式,可能被...

    分布式程序java 实验名称 基于Java RMI的C/S编程实验

    在实验"基于Socket的C/S编程实验"中,学生将学习如何创建和管理这些Socket连接,以及如何在客户端和服务器之间交换数据。 接着,我们转向基于Java RMI的C/S编程。Java RMI是一种高级的通信机制,它允许在Java应用...

    java实现简单实现C/S应用

    利用Socket编程实现C/S应用。其中,Client端为GUI程序,用于提供界面输入两个数,并有1个“发送”按钮,另外还有一个 TextField用于显示传来的计算结果;Server端用于监听连接请求、计算发送过来的两数的和、送回...

    Java实现C/S架构的聊天系统

    Java的Socket编程是实现C/S通信的关键。Socket是TCP/IP协议的一部分,用于两个网络应用程序之间建立连接,进行双向通信。在聊天系统中,服务器会创建一个监听Socket,等待客户端的连接请求。一旦连接建立,客户端和...

    socket实现c/s结构示例代码

    本示例将探讨如何使用Java语言来构建一个基于C/S(客户端/服务器)架构的系统,通过Socket进行通信。 首先,我们要了解C/S架构。C/S(Client/Server)架构是一种常见的网络应用程序模型,其中客户端(Client)发起...

    基于Java实现C/S架构的聊天系统

    在这个聊天系统中,每个客户端都会建立一个到服务器的Socket连接,通过这个连接,客户端可以发送消息到服务器,服务器也可以将消息推送给客户端。Socket通信通常涉及套接字的创建、连接、读写和关闭等步骤。 多线程...

    学习JAVA—网络编程之Socket、ServerSocket、C/S模式

    总之,Java的Socket和ServerSocket提供了强大的网络编程能力,通过C/S模式实现了客户端和服务器之间的高效通信。通过深入学习和实践,你可以掌握构建分布式应用程序的基础,为更复杂的网络项目打下坚实基础。

    java课程设计(c/s)

    【Java课程设计(C/S)】是针对计算机科学与技术专业学生的一项实践任务,旨在让学生深入理解客户端/服务器(Client/Server,C/S)架构,并掌握使用Java编程语言进行系统开发的技术。在这个项目中,学生们通常会被...

    Java聊天室c/s开发

    在本文中,我们将深入探讨Java聊天室的C/S(客户端/服务器)开发,这是一个常见的分布式系统架构模式,广泛应用于各种在线交互式应用,包括聊天、游戏等。在Java中实现C/S模式的聊天室,我们可以利用Java丰富的网络...

    Java网络编程(18个Socket C/S实例)

    `Java网络编程.ppt`是一个演示文稿,可能会详细解释网络编程的基本概念,包括IP地址、端口号、套接字(Socket)的工作原理,以及如何使用Java的`java.net`包来实现这些功能。 在"多客户服务器相互通信"的子目录下,...

    基于C/S模式的Java聊天室

    【标题】"基于C/S模式的Java聊天室"是一个典型的网络通信项目,它采用客户机/服务器(Client/Server,简称C/S)架构,通过Java编程语言实现。在这个模式下,客户端作为用户交互的界面,负责发送和接收聊天信息;而...

    基于C/S模式的JAVA聊天室

    2. **网络编程**:JAVA提供了Socket编程接口,可以创建TCP/IP连接,这是C/S模式的基础。通过Socket,客户端能够与服务器建立连接,交换数据。 3. **多线程**:在聊天室中,服务器端需要同时处理多个客户端的连接...

    基于Java C/S模式的简单学生管理系统

    【基于Java C/S模式的简单学生管理系统】是一个利用Java编程语言实现的客户端/服务器(Client/Server,C/S)架构的软件应用,主要用于演示学生信息的管理。由于它并未包含管理员功能,所以其功能可能相对基础,适用...

    C/S的一个简单实现

    C/S架构下的Java Socket编程实现 本资源是关于C/S架构下的Java Socket编程实现,通过客户端和服务器端的代码实现了基本的访问功能。 Socket编程 Socket编程是指通过使用Socket对象来实现网络编程的方法。在Java...

    C/S模式下的java图书管理系统

    《C/S模式下的Java图书管理系统详解》 C/S(Client/Server)模式是一种常见的软件架构模式,它将应用逻辑分为客户端(Client)和服务器端(Server)两部分,客户端负责用户交互,服务器端则处理数据存储和管理。在...

Global site tag (gtag.js) - Google Analytics