- 浏览: 182652 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
goldmaster:
if re.findall('[gb18030].', s): ...
python 字符串中的中文识别 -
chenwq:
这个我们在做啊!CB-DDM!
基于云计算的数据挖掘 -
Liverpool_IT:
prefuse怎么画有向图啊,就是边带箭头的那种,QQ 112 ...
Use prefuse with database -
bjsnail:
我草,我就烦这说话中西合璧的,装蛋
java enum 学习 -
ct455332:
tks a lot!
java enum 学习
老师留作业了,是一道网络编程题目,socket知识在先,requirement如下:
- 用一种编程语言实现一个简单的Server/Client程序;
- 该程序的主要功能是利用Client从Server端下载一个文件;
- 在下载之前,需要有一定的用户身份验证机制(说白了就是先输入以下用户名和密码);
- Server应该是多线程机制的,即为每个Client请求Server都要有一个线程去处理,而不是所有的Client都是一个Server线程处理。
ok,这就是需求,单从编程角度来讲,题目不难,单老师说过一句话,我觉得非常有道理,“看一万个程序,不如自己亲自写一个程序,写一万个程序,不如努力写一个好程序”,所以我就利用十一假期的最后两天,完成了这样一个作业,当然大部分时间还是画在了学习不太熟悉的python上。在这里,还要感谢一下CSDN上“wumingabc的专栏”的一篇blog,参考了他的一些代码。
废话少说,上code(这篇是java版,python版):
处理流程:
- 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关于data server/client的小小程序"中,我们将会探讨如何利用Java构建一个简单的聊天系统,它涉及到服务器和客户端之间的数据传输。这个程序由两个主要部分组成:DateServer.java和DateClient....
`client.java` 或 `UDPClient.java` 文件则代表了客户端的实现。客户端也需要创建一个`DatagramSocket` 对象,但它主要用来发送数据到服务器。客户端使用`DatagramPacket` 类包装要发送的数据,指定服务器的IP地址和...
在Java编程领域,多线程Client/Server程序是网络编程中的一个重要组成部分,它允许服务器同时处理多个客户端的请求。在本程序中,`ChatServer.java` 和 `ChatClient.java` 文件可能分别代表了服务器端和客户端的核心...
远程控制编码技术是一种在计算机网络中实现一台设备(通常称为客户端或client)对另一台设备(服务器或server)进行操作的技术。这种技术广泛应用于系统管理、技术支持、远程协作以及自动化任务执行等领域。在这个...
在这个“server/client 多用户通信”项目中,我们将深入探讨如何使用Socket来构建异步式、消息驱动的系统,以支持多个客户端同时与服务器进行交互。 首先,让我们从基础概念开始。`ServerSocket`是Java提供的一个类...
在这个项目中,"Java swing实现简单的C/S聊天及文件传输系统"是利用Swing构建一个客户端/服务器(Client/Server)架构的聊天和文件传输应用。这个系统允许用户通过网络进行文本聊天并交换文件。以下是关于这个项目的...
在本文中,我们将探讨如何使用Java来实现一个简单的Server/Client回显功能。回显功能是一种常见的网络通信示例,其中服务器接收客户端发送的数据并将其原样返回给客户端。这通常用于验证网络连接和基本的通信协议...
在这个名为"ServerQQ"的项目中,开发者利用Java的多线程特性实现了客户端(Client)与服务器端(Server)的聊天功能,模拟了类似于QQ的即时通讯体验。下面我们将深入探讨这个项目中的关键技术点。 一、Java多线程 ...
在Java中,我们可以使用JSSE(Java Secure Socket Extension)来实现SSL服务器和客户端的通信。下面将详细介绍如何使用JAVA实现SSL服务器和客户端的通信。 首先,理解SSL的基本流程是必要的。SSL通信通常包括以下...
在这个“server_client(simpleness).rar_JAVA实现C/S”项目中,开发者提供了一个简单的C/S架构实现,对于初学者来说是很好的学习材料。下面将详细解释这个项目的相关知识点。 首先,C/S架构的基本概念:在这种架构...
其中,Client端为GUI程序,用于提供界面输入两个数,并有1个“发送”按钮,另外还有一个 TextField用于显示传来的计算结果;Server端用于监听连接请求、计算发送过来的两数的和、送回数据结果。
这个“java 实现的mina server client完全能用的”项目可能包含了一个完整的Mina服务器和客户端实现,使得开发者能够快速构建基于TCP或UDP的网络应用。 在Java Mina中,Server是服务端,它监听特定的端口,等待...
java cas server 集成 java cas client 和 net client 附带文档,问题解决方法,源码,jar包,包含技术有java cas,cfx,LDAP,net cas。核心在于集成了net client,,上传太小,不能传源码,有需要的加群。有兴趣的...
这个系统利用了Java的非阻塞I/O(NIO)机制,Socket通信以及多线程IO操作来实现一系列的功能,包括好友管理、聊天交互和文件传输,对于Java学习者来说是一个很好的实践和提升平台。 首先,让我们来了解C/S架构。在C...
【JAVA实现的C/S模式的聊天室程序代码】是一个基于Java编程语言开发的客户端/服务器端(Client/Server,简称C/S)架构的聊天应用程序。在这个项目中,开发者旨在创建一个平台,允许多个用户通过网络实时交流,共享...
在这个场景中,我们有`TCP client.java`和`TCP server.java`两个文件,分别代表了TCP客户端和服务器端的Java实现。接下来,我们将深入探讨这两个关键组件的工作原理以及如何在Java中进行TCP Socket编程。 首先,TCP...
Java仿照FTP(File Transfer Protocol)制作的TCP/IP文件传输Demo是一个典型的网络编程示例,它利用Java的Socket编程来实现文件的发送和接收。FTP协议是互联网上用于在主机之间传输文件的标准协议,而这个Demo则展示...
本项目通过"java实现文件传输(上传下载)",旨在教你如何构建一个简单的文件上传和下载系统。以下是对这个项目及其相关知识点的详细解释。 首先,让我们分析一下项目的组成部分: 1. **client**:这是客户端的...
在IT领域,网络通信是不可或缺的一部分,而TCP(Transmission Control Protocol)作为一种面向连接的、可靠的传输层协议,常被用于实现文件的传输。本项目"SOCKET TCP 文件传输 客户端 服务器端 client svever"就是...
压缩包中的"Test1"文件可能是包含Server和Client代码的Java源文件。通常,Server代码会包含一个无限循环,不断接受新的客户端连接,直到服务器关闭。Client代码则包含一个简单的用户界面,允许用户输入字符并发送到...