精华内容
下载资源
问答
  • 最近研究Android与后台进行Socket通讯,在后台获取到客户端socket对象时,给客户端发送一条数据对象,这时候会用到输入与输出,来传输数据,而数据是要经过序列化之后才能传输。到客户端数据在经过反序列...

    最近研究Android与后台进行Socket通讯,在后台获取到客户端的socket对象时,给客户端发送一条数据对象,这时候会用到输入流与输出流,来传输数据,而数据是要经过序列化之后才能传输的。到客户端的数据在经过反序列化,获取数据对象,但是在运行过程中总是报ClassNotFoundException。

    1.ClassNotFoundException解决方法:

    将服务端与客户端的包名修改成一样的,如下图所示:

    Android端:

    服务器端:

    这个时候如果服务器与客户端的jdk版本一样应该就灭有问题了, 可偏偏楼主的两个jdk版本不一样,在反序列化的时候报了java.io.InvalidClassException,产生这个问题的原因是:序列化之后的对象都会唯一对应一个serialVersionUID的长整形数据来唯一标识该序列化对象。这个是由jdk自己计算出来的,当然应该也可以自己定义。当客户端与服务器端计算的serialVersionUID值不一样就能会报java.io.InvalidClassException这个错,解决的方法是将客户端与服务器端的serialVersionUID保持一致,这样就可以解决问题了。

    Eclips/MyEclispe生成方法:

    序列化的类如果没有serialVersionUID,该类下会有警告的黄线,将鼠标移动到黄线上,会出现解决Tips,点击第一个或者第二个都行,图示如下:

     ok,解决!

    另贴上传输序列化对象的方法:

    服务器向客户端发送序列化后的数据
    
    //获取输出流对象
    OutputStream os = mSocket.getOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(os);
    //将信息对象写入输出流
    oos.writeObject(msg);//msg序列化的对象
    oos.flush();

    客户端反序列化,获取数据对象

    ChatMessage chatMessage;
    try {
          ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
          Object object = ois.readObject();
          if (object != null){
              chatMessage =(ChatMessage)object;
              sendObjMsgToHandler(SOCKETMSG,chatMessage); //发送包含ChatMessage对象的信息到Handler,在Ui线程更新数据
     }catch (Exception e) {
          e.printStackTrace();
     }
    展开全文
  • 实现简单HTTP服务器-图片与CGI

    千次阅读 2015-07-29 12:51:21
    并不复杂,大概300行,就可以实现发送图片,和执行CGI程序将结果返回给客户端。具体实现过程服务器代码:代码量比较少,而且添加了一些注释,简明易懂。 csapp.h是该书通用头文件,定义了一些常量,以及进一步...

    简介

    在学习了深入理解操作系统第11章的内容后,更加深刻的理解的Socket,IO流,fork,Cgi 以及Http等知识。并且学习了HTTP服务器的代码实现。并不复杂,大概300行,就可以实现发送图片,和执行CGI程序将结果返回给客户端。

    具体实现过程

    服务器代码:

    代码量比较少,而且添加了一些注释,简明易懂。
    csapp.h是该书的通用头文件,定义了一些常量,以及进一步封装了一些系统调用(检查返回值等)。对应的函数实现代码为csapp.c
    (全书的代码网上有资源)

    #include "csapp.h"
    
    void doit(int fd);
    void read_requesthdrs(rio_t *rp);
    int parse_uri(char *uri, char *filename, char *cgiargs);
    void serve_static(int fd, char *filename, int filesize);
    void get_filetype(char *filename, char *filetype);
    void serve_dynamic(int fd, char *filename, char *cgiargs);
    void clienterror(int fd, char *cause, char *errnum, 
             char *shortmsg, char *longmsg);
    
    int main(int argc, char **argv) 
    {
        int listenfd, connfd, port, clientlen;
        struct sockaddr_in clientaddr;
    
        /* 检查命令行输入 */
        if (argc != 2) {
        fprintf(stderr, "usage: %s <port>\n", argv[0]);
        exit(1);
        }
        port = atoi(argv[1]); //获取服务器端口号
    
        //循环监听客户端请求
        listenfd = Open_listenfd(port);
        while (1) {
        clientlen = sizeof(clientaddr);
        connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); //接收客户端的请求
        doit(connfd);                                             //执行服务
        Close(connfd);                                            //关闭与客户端的连接
        }
    }
    /* $end tinymain */
    
    /*
     * doit - 处理一个Http请求
     */
    /* $begin doit */
    void doit(int fd) 
    {
        int is_static;  //是否为静态请求
        struct stat sbuf;
    
        char buf[MAXLINE], 
        method[MAXLINE], //请求方法 
        uri[MAXLINE],    //uri路径
        version[MAXLINE]; //MAXLINE:8192
    
        char filename[MAXLINE],  //文件名
        cgiargs[MAXLINE]; //cgi程序的参数
        rio_t rio;
    
    
        //读取客户的请求 以及HTTP头文件 
        //Rio_readinitb是封装过的IO读取函数
        Rio_readinitb(&rio, fd);
        Rio_readlineb(&rio, buf, MAXLINE);    //读取请求              
        sscanf(buf, "%s %s %s", method, uri, version);   //解析请求 
        if (strcasecmp(method, "GET")) {             //只能提供GET   
           clienterror(fd, method, "501", "Not Implemented",
                    "Tiny does not implement this method");
            return;
        }                                
        read_requesthdrs(&rio);            //读取请求头 
    
    
        //从浏览器的输入栏中解析GET请求
        is_static = parse_uri(uri, filename, cgiargs);       //静态图片 / 动态加法请求检查
        if (stat(filename, &sbuf) < 0) {                  //没有用户所请求的文件   
        clienterror(fd, filename, "404", "Not found",
                "Tiny couldn't find this file");
        return;
        }                                                    //line:netp:doit:endnotfound
    
        if (is_static) { /* 静态请求,返回图片*/          
        if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { //line:netp:doit:readable
            clienterror(fd, filename, "403", "Forbidden",
                "Tiny couldn't read the file");
            return;
        }
        serve_static(fd, filename, sbuf.st_size);        //将图片发送给客户端
        }
        else { /* 调用CGI程序执行加法运算*/
        if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { 
            clienterror(fd, filename, "403", "Forbidden",
                "Tiny couldn't run the CGI program");
            return;
        }
        serve_dynamic(fd, filename, cgiargs);            //动态服务,传入参数给cgi程序
        }
    }
    /* $end doit */
    
    /*
     * read_requesthdrs - read and parse HTTP request headers
     */
    /* $begin read_requesthdrs */
    void read_requesthdrs(rio_t *rp) 
    {
        char buf[MAXLINE];
    
        Rio_readlineb(rp, buf, MAXLINE);
        while(strcmp(buf, "\r\n")) {          //HTTP Header 规定以\r\n结尾
        Rio_readlineb(rp, buf, MAXLINE);
        printf("%s", buf);
        }
        return;
    }
    /* $end read_requesthdrs */
    
    /*
    *
     *  解析浏览器发来的URI中的文件名 或者 是 CGI参数(加法的两个数)
     *  返回值:0为动态CGI,1为静态图片
     */
    /* $begin parse_uri */
    int parse_uri(char *uri, char *filename, char *cgiargs) 
    {
        char *ptr;
    
        if (!strstr(uri, "cgi-bin")) {  /* Static content */ //line:netp:parseuri:isstatic
        strcpy(cgiargs, "");                             //line:netp:parseuri:clearcgi
        strcpy(filename, ".");                           //line:netp:parseuri:beginconvert1
        strcat(filename, uri);                           //line:netp:parseuri:endconvert1
        if (uri[strlen(uri)-1] == '/')                   //line:netp:parseuri:slashcheck
            strcat(filename, "home.html");               //line:netp:parseuri:appenddefault
        return 1;
        }
        else {  /* Dynamic content */                        //line:netp:parseuri:isdynamic
        ptr = index(uri, '?');                           //line:netp:parseuri:beginextract
        if (ptr) {
            strcpy(cgiargs, ptr+1);
            *ptr = '\0';
        }
        else 
            strcpy(cgiargs, "");                         //line:netp:parseuri:endextract
        strcpy(filename, ".");                           //line:netp:parseuri:beginconvert2
        strcat(filename, uri);                           //line:netp:parseuri:endconvert2
        return 0;
        }
    }
    /* $end parse_uri */
    
    /*
     * 
     * 静态服务 : 拷贝图片返回给客户
     */
    /* $begin serve_static */
    void serve_static(int fd, char *filename, int filesize) 
    {
        int srcfd;
        char *srcp, filetype[MAXLINE], buf[MAXBUF];
    
        /* 发送服务器响应Header给客户端 */
        get_filetype(filename, filetype);       //line:netp:servestatic:getfiletype
        sprintf(buf, "HTTP/1.0 200 OK\r\n");    //line:netp:servestatic:beginserve
        sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);
        sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);
        sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);
        Rio_writen(fd, buf, strlen(buf));       //line:netp:servestatic:endserve
    
        /* 通过内存映射,发送文件 */
        srcfd = Open(filename, O_RDONLY, 0);    //line:netp:servestatic:open
        srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmap
        Close(srcfd);                           //line:netp:servestatic:close
        Rio_writen(fd, srcp, filesize);         //line:netp:servestatic:write
        Munmap(srcp, filesize);                 //line:netp:servestatic:munmap
    }
    
    /*
     * 
     * 获取文件类型
     */
    void get_filetype(char *filename, char *filetype) 
    {
        if (strstr(filename, ".html"))
        strcpy(filetype, "text/html");
        else if (strstr(filename, ".gif"))
        strcpy(filetype, "image/gif");
        else if (strstr(filename, ".jpg"))
        strcpy(filetype, "image/jpeg");
        else
        strcpy(filetype, "text/plain");
    }  
    /* $end serve_static */
    
    /*
     * 
     * 动态服务:执行CGI程序,将结果返回给客户端(浏览器显示加法结果)
     */
    /* $begin serve_dynamic */
    void serve_dynamic(int fd, char *filename, char *cgiargs) 
    {
        char buf[MAXLINE], *emptylist[] = { NULL };
    
        /* Return first part of HTTP response */
        sprintf(buf, "HTTP/1.0 200 OK\r\n"); 
        Rio_writen(fd, buf, strlen(buf));
        sprintf(buf, "Server: Tiny Web Server\r\n");
        Rio_writen(fd, buf, strlen(buf));
    
        //创建子进程
        if (Fork() == 0) { /* child */ //line:netp:servedynamic:fork
        /* Real server would set all CGI vars here */
        //发送环境变量
        setenv("QUERY_STRING", cgiargs, 1); 
        //重定向stdout
        Dup2(fd, STDOUT_FILENO);         
        //执行服务器上的CGI程序
        Execve(filename, emptylist, environ); 
        }
        Wait(NULL); // 父进程等待子进程结束并回收
    }
    /* $end serve_dynamic */
    
    /*
     * 
     * 返回请求错误消息给客户端
     */
    /* $begin clienterror */
    void clienterror(int fd, char *cause, char *errnum, 
             char *shortmsg, char *longmsg) 
    {
        char buf[MAXLINE], body[MAXBUF];
    
        /* Build the HTTP response body */
        sprintf(body, "<html><title>Tiny Error</title>");
        sprintf(body, "%s<body bgcolor=""ffffff"">\r\n", body);
        sprintf(body, "%s%s: %s\r\n", body, errnum, shortmsg);
        sprintf(body, "%s<p>%s: %s\r\n", body, longmsg, cause);
        sprintf(body, "%s<hr><em>The Tiny Web server</em>\r\n", body);
    
        /* Print the HTTP response */
        sprintf(buf, "HTTP/1.0 %s %s\r\n", errnum, shortmsg);
        Rio_writen(fd, buf, strlen(buf));
        sprintf(buf, "Content-type: text/html\r\n");
        Rio_writen(fd, buf, strlen(buf));
        sprintf(buf, "Content-length: %d\r\n\r\n", (int)strlen(body));
        Rio_writen(fd, buf, strlen(buf));
        Rio_writen(fd, body, strlen(body));
    }
    /* $end clienterror */

    Cgi程序-加法器adder.c :

    #include "csapp.h"
    
    int main(void) {
        char *buf, *p;
        char arg1[MAXLINE], arg2[MAXLINE], content[MAXLINE];
        int n1=0, n2=0;
    
        /* Extract the two arguments */
        if ((buf = getenv("QUERY_STRING")) != NULL) {
        p = strchr(buf, '&');
        *p = '\0';
        strcpy(arg1, buf);
        strcpy(arg2, p+1);
        n1 = atoi(arg1);
        n2 = atoi(arg2);
        }
    
        /* Make the response body */
        sprintf(content, "Welcome to add.com: ");
        sprintf(content, "%sTHE Internet addition portal.\r\n<p>", content);
        sprintf(content, "%sThe answer is: %d + %d = %d\r\n<p>", 
            content, n1, n2, n1 + n2);
        sprintf(content, "%sThanks for visiting!\r\n", content);
    
        /* Generate the HTTP response */
        printf("Content-length: %d\r\n", (int)strlen(content));
        printf("Content-type: text/html\r\n\r\n");
        printf("%s", content);
        fflush(stdout);
        exit(0);
    }
    /* $end adder */

    HTTP服务器目录结构

    cgi-bin中存放编译好的adder.c的二进制adder.o文件:
    这里写图片描述

    运行HTTP服务器

    这里写图片描述

    linux环境下浏览器请求服务

    1)静态服务,返回图片

    这里写图片描述

    2)CGI动态服务,返回加法结果:

    这里写图片描述

    服务器输出日志

    这里写图片描述

    展开全文
  • FTP服务器 C#

    2018-03-10 09:40:05
    用VS编写FTP服务器软件,C#网络程序编程学习用。 代码: using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; using System.Net.Sockets; using ...
  •  forward是服务器请求资源,服务器直接访问目标地址URL,把那个URL响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来,所以它地址栏中还是原来地址。...
  • 一般情况下,会为每个连接配套一条独立的线程,或者说一条线程维护一个连接成功的IO流的读写。在并发量小的情况下,这个没有什么问题。但是,当在高并发的场景下,需要大量的线程来维护大量的网络连接,内存、线程...
  • java源码包---java 源码 大量 实例

    千次下载 热门讨论 2013-04-18 23:15:26
     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定的e-...
  • 同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定e-mail账号,查询mail 服务器的会话…… 还包括消息客户端程序,通过连接创建会话。创建发送者和映射消息。发送消息,同时对文本...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定的e-...
  • Serverless 是指构建和运行不需要服务器管理应用程序概念。(<a href="https://github.com/cncf/wg-serverless/tree/master/whitepapers/serverless-overview">serverless-overview) <p>Serverless computing ...
  • java源码包2

    千次下载 热门讨论 2013-04-20 11:28:17
     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定的e-...
  • java源码包3

    千次下载 热门讨论 2013-04-20 11:30:13
     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定的e-...
  • java源码包4

    千次下载 热门讨论 2013-04-20 11:31:44
     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定的e-...
  • 同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定e-mail账号,查询mail 服务器的会话…… 还包括消息客户端程序,通过连接创建会话。创建发送者和映射消息。发送消息,同时对文本...
  • 同时一个mail note将被发送给消息发送者,发送一个e-mail通知由recipient参数确定e-mail账号,查询mail 服务器的会话…… 还包括消息客户端程序,通过连接创建会话。创建发送者和映射消息。发送消息,同时对文本...
  • 11:客户端发送的地址有误,不予响应 20:服务端发送相对目录地址到客户端,客户端接到信息创建目录 21:服务端发送相对文件地址到客户端,客户端接到信息创建文件 22:开始发送数据,发送文件长度 31:数据发送完成 ...
  • java 面试题 总结

    2009-09-16 08:45:34
    forward是服务器请求资源,服务器直接访问目标地址URL,把那个URL响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来,所以它地址栏中还是原来地址。 redirect...
  • Android 上百实例源码分析以及开源分析 集合打包4

    千次下载 热门讨论 2012-07-10 21:54:03
    在Jamendo中,主要是通过再定义一个SeparatedListAdapter来进行这个工作,我们来看看它是怎么实现:我理解Adapter过程,首先通过调用getCount()来获得总Row数目,然后对一行调用getView进行绘制,因此要实现在...
  • 基本socket编程,介绍socket编程基本步骤,启动socket服务器后,在打开socket客户端,在输入框里输入消息发送服务器服务器受到消息后返回给客户端; Http服务器,httpsever.java; 一个支持多线程的服务器...
  • mycli:支持自动补全和语法高亮 MySQL 命令行客户端 pgcli:支持自动补全和语法高亮 Postgres 命令行工具。 SAWS:一个加强版 AWS 命令行。 Shell xonsh:一种基于 python 跨平台,面向 unix shell...
  • 网络转发支持多个目标IP,这样就实现了本地采集软件,自由将数据转到客户端,随时查看探测器数据。 自动记住用户最后停留界面+其他信息,重启后自动应用。 报警自动切换到对应地图,探测器按钮闪烁。 双击探测...
  • SSO-WebDemo

    2013-08-12 20:25:57
    这样方式大大区别于传统(Client/Server)C/S结构,在那样应用中,客户端服务器端会建立一个长时间专用连接通道。正是因为有了无状态特性,每个连接资源能够很快被其他客户端所重用,一台Web服务器才...
  • Java JDK实例宝典

    2016-06-16 19:27:14
    4 使用异常技巧与原则 第7章 IO——输入输出 7. 1 获取文件属性信息 7. 2 列出指定目录下文件 7. 3 创建文件和目录 7. 4 删除文件和目录 7. 5 移动文件和目录 7. 6 复制文件和...
  • 在进入削峰队列之前,需要判断mq中消息数目是否过多,如果超过设定数量限制,直接返回给客户端"已售罄" channel.messageCount("seckill") 可以获取到队列中当前到ready消息数目 见接口 ...
  • Java JDK实例宝典(代码+清单)

    千次下载 热门讨论 2008-05-13 21:16:25
    4 使用异常技巧与原则 第7章 IO——输入输出 7. 1 获取文件属性信息 7. 2 列出指定目录下文件 7. 3 创建文件和目录 7. 4 删除文件和目录 7. 5 移动文件和目录 7. 6 复制文件和...
  • 4 使用异常技巧与原则 第7章 IO——输入输出 7. 1 获取文件属性信息 7. 2 列出指定目录下文件 7. 3 创建文件和目录 7. 4 删除文件和目录 7. 5 移动文件和目录 7. 6 复制文件和...
  • ServerSocket功能是用来使本程序变成一个服务器程序,可以对外服务(对攻击者敞开大门)。Socket最初是在Unix上出现,后来微软将它引入了Windows中(包括Win98和WinNt);后两个控件作用是用来使程序具有FTP...

空空如也

空空如也

1 2
收藏数 31
精华内容 12
关键字:

服务器给客户端发送io流的过程