2014,迟到的你好

无疑是最艰难的一年,

自己把自己搞定一团糟,

最后开始怀疑自己还是以前的自己吗

是真心的吗

这世上太多浮华喧闹

都是历练


愿求一份谅解

是的,看得很重,很敏感


2014 ,你好

Tags: 心情
Time: 1389982923346

新起点

以前,喜欢一个人

现在,喜欢一个人

给自己一个目标

继续前行

看梦想花开

蓝天下

我在人群中看着自己


反倒笑了


Tags: 心情 Objective-C
Time: 1386778483812

nodejs+c实现的回射程序

最近在看《UNIX编程卷1:套接字联网API》,一般都是ssh到本地的linux虚拟机里启动服务器端,然后再另一个ssh窗口启动客户端来测试。今天想了想可用nodejs在windows下实现回射程序的客户端:

echoCli.js:

var net = require('net'),
  readline = require('readline');
var serverInfo = {
  "host": "192.168.147.128",
  "port": 9983
};
var client = net.connect(serverInfo);
client.on('data', function(data) {
  console.log(data.toString());
});
client.on('end', function() {
  console.log('client disconnected');
});
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
rl.on('line', function (str) {
  client.write(str);
});

echoServer.c:

#include <stdlib.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "../common.h"
#line 18 "tcpechoserv01.c"
void str_echo(int fd);
void sig_chld(int signo);
int main(void)
{
    // 注册信号处理函数
    signal(SIGCHLD, sig_chld);
    int sockfd, connfd;
    struct sockaddr_in servaddr, cliaddr, tmpaddr;
    char addr_str[INET_ADDRSTRLEN + 1];
    socklen_t cliaddrlen, tmplen;
    pid_t pid;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0) {
        perror("socket error");
        return 1;
    }
    bzero(&cliaddr, sizeof(cliaddr));
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(9983);
    if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
        perror("bind error");
        return 1;
    }
    if (listen(sockfd, 1024) != 0) {
        perror("listen error");
        return 1;
    }
    // 输出服务器绑定的ip和端口号,tmplen初始化是必须的,不然会出错
    tmplen = sizeof(tmpaddr);
    if (getsockname(sockfd, (struct sockaddr *)&tmpaddr, &tmplen) != 0) {
        perror("getsockname error");
        return 1;
    }
    inet_ntop(AF_INET, (struct in_addr *)&tmpaddr.sin_addr, addr_str, sizeof(addr_str));
    printf("listen IP: %s, PORT: %d\n", addr_str, ntohs(tmpaddr.sin_port));
    for(;;) {
        connfd = accept(sockfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
        if (connfd < 0) {
            // 处理由信号引起的系统调用中断
            if (errno == EINTR) {
                continue;
            }
            perror("accept error");
            exit(1);
        }
        // 子进程
        if ((pid = fork()) == 0) {
            // 打印客户端IP和端口
            printf("child-process: client IP: %s, PORT: %d\n", inet_ntop(AF_INET, (struct in_addr *)&cliaddr.sin_addr, addr_str, sizeof(addr_str)), ntohs(cliaddr.sin_port));
            // 关闭引用
            if (close(sockfd) != 0){
                perror("child-process: close sockfd error");
                exit(1);
            }
            // 回射
            str_echo(connfd);
            // 子进程结束会关闭所有打开的描述符
            exit(0);
        }
        // 父进程关闭connfd,减少引用数
        if (close(connfd) != 0){
            perror("parent-process: close connfd error");
            exit(1);
        }
    }
}
/**
 * 回射字符串函数
 */
void str_echo(int fd)
{
    ssize_t n;
    char buff[MAXLINE];
    printf("str_echo: before read.\n");
    again:
    while((n = read(fd, buff, MAXLINE-1)) > 0) {
        writen(fd, buff, n);
    }
    if (n < 0 && errno == EINTR) {
        goto again;
    } else if (n < 0) {
        perror("str_echo: read error");
        exit(1);
    }
}
/**
 * 信号:SIGCHLD处理函数
 */
void sig_chld(int signo)
{
    pid_t pid;
    int stat;
    // wait会错过信号
    //pid = wait(&stat);
    // -1: 等待第一个终止的子进程
    while((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        // 在信号处理函数中调用IO操作是不合理的
        printf("child %d terminated\n", pid);
    }
    return;
}

common.c:

#include "common.h"
// static 会把int默认值设置为0
static int read_cnt;
static char *read_ptr;
static char read_buff[MAXLINE- 1];
/**
 * 每次读一个字符
 */
static size_t my_read(int fd, char *ptr)
{
    if (read_cnt <= 0) {
        again:
            if ((read_cnt = read(fd, read_buff, sizeof(read_buff))) < 0) {
                if (errno == EINTR) {
                    goto again;
                }
                return (-1);
            } else if (read_cnt == 0) {
                return (0);
            }
            read_ptr = read_buff;
    }
    read_cnt --;
    *ptr = *read_ptr++;
    return (1);
}
/**
 * 指示buff的函数,void指针会自动转换
 */
size_t readlinebuf(void **vptrptr)
{
    if (read_cnt) {
        *vptrptr = read_ptr;
    }
    return (read_cnt);
}
/**
 * 每次读n个字符
 */
size_t readn(int fd, void *vptr, size_t n)
{
    size_t nleft;
    size_t nread;
    char *ptr;
    ptr = vptr;
    nleft = n;
    while(nleft > 0) {
        if ((nread = read(fd, ptr, nleft)) < 0) {
            if (errno == EINTR) {
                nread = 0;
            } else {
                return (-1);
            }
        } else if (nread == 0) {
            break;
        }
        nleft -= nread;
        ptr   += nread;
    }
    return (n - nleft);
}
/**
 * 每次写n个字符
 */
size_t writen(int fd, const void *vptr, size_t n)
{
    size_t nleft;
    size_t nwritten;
    const char * ptr;
    ptr = vptr;
    nleft = n;
    while(nleft > 0) {
        if ((nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR) {
                nwritten = 0;
            } else {
                return (-1);
            }
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return (n);
}
size_t readline(int fd, void *vptr, size_t maxlen)
{
    size_t nleft, nread;
    char *ptr, c;
    ptr = vptr;
    nleft = maxlen;
    // 保留一字节的空字符位置
    while(nleft > 1 && (nread = my_read(fd, &c)) != 0) {
        if(nread == 1) {
            *ptr++ = c;
            nleft --;
            if (c == '\n') {
                break;
            }
        } else if (nread < 0) {
            if (errno == EINTR) {
                continue;
            }
            return (-1);
        }
    }
    *ptr = 0;
    return (maxlen - nleft);
}
/**
 * 老的readline函数
 */
size_t readline_old(int fd, void *vptr, size_t maxlen)
{
    size_t n, rc;
    char c, *ptr;
    ptr = vptr;
    // n = 1,保留一个空字符
    for (n = 1; n < maxlen; n++) {
        again:
        if((rc = read(fd, &c, 1)) == 1) {
            *ptr++ = c;
            if (c == '\n') {
                break;
            }
        } else if (rc == 0) {
            // 尾部放入空字符
            *ptr = 0;
        } else {
            if (errno == EINTR) {
                goto again;
            }
            return (-1);
        }
    }
    *ptr = 0;
    return (n);
}

common.h:

#include <unistd.h>
#include <errno.h>
#ifndef MAXLINE
#define MAXLINE 4096
#endif
size_t readn(int fd, void *buff, size_t n);
size_t writen(int fd, const void *buff, size_t n);
size_t readline(int fd, void *buff, size_t maxlen);
size_t readline_old(int fd, void *buff, size_t maxlen);

协议是沟通的桥梁。

Tags: nodejs c unp
Time: 1385048934876

二〇一三双十一

昨天是众所周知的双11光棍节。人们都忙着购物刷网页,而我却...

一年中比较特别日子屈指可数:爸妈生日、7月15、1月1日,还有就是今天了。今天对我有特殊的意义:两年前的今天走出校园,两年前的今天注册新浪微博。有一个奇怪的现象:我总是看到11:11,特别2011年11月11号早上11点11分竟然让我看见了!当时我就呆了。后来从一个唯物主义者的角度想可能的原因:

  1. 我经常睡懒觉,大部分时间是11点多起床的

  2. 大学上课经常11点上最后一节课,准备着吃午饭

人为什么会把这种毫无关联的东西强加在自己身上呢!初恋是无罪的,可是孤独难过的时候却会深深的想着她,然后痛苦更加痛苦以致麻木。人孤独无依地生存在宇宙之中,创造各种事物情感来麻醉自己。人活着就是为了"有"、"欲望"。我也有欲望,但我知道那愿望却无法实现,所以会从另外一个角度看,会很冷静。哀兵必胜,大概是形容我这种人吧。对什么都不在乎了反而能获得一种洞察世界的心境——这或许是这些年来最大的收获。

周日去外面,一传教士走过来问我对圣经感兴趣吗...这种情况我已经遇到过很多次了。难道是主又派人来帮助我脱离苦海?有个幽默笑话是这样的:

一个人掉进水里快要淹死了,这时有只船过来问:"需要帮忙吗?"
他说:"不用,谢谢,上帝会来救我的"
后来又来了一只船,问:"需要帮忙吗?"
他说:"不用,谢谢,上帝会来救我的"
后来,他淹死了,去了天堂,问:"上帝啊,为什么你不救我?"
上帝说:"我不是派了两艘船去救你了吗?笨蛋"

一句"笨蛋"骂了多少人...而我却宁愿一直笨下去。

这,又有什么关系!

Tags: 心情
Time: 1384187360625