2014,迟到的你好
无疑是最艰难的一年,
自己把自己搞定一团糟,
最后开始怀疑自己还是以前的自己吗
是真心的吗
这世上太多浮华喧闹
都是历练
愿求一份谅解
是的,看得很重,很敏感
2014 ,你好
新起点
以前,喜欢一个人
现在,喜欢一个人
给自己一个目标
继续前行
看梦想花开
蓝天下
我在人群中看着自己
反倒笑了
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);
协议是沟通的桥梁。
二〇一三双十一
昨天是众所周知的双11光棍节。人们都忙着购物刷网页,而我却...
一年中比较特别日子屈指可数:爸妈生日、7月15、1月1日,还有就是今天了。今天对我有特殊的意义:两年前的今天走出校园,两年前的今天注册新浪微博。有一个奇怪的现象:我总是看到11:11,特别2011年11月11号早上11点11分竟然让我看见了!当时我就呆了。后来从一个唯物主义者的角度想可能的原因:
我经常睡懒觉,大部分时间是11点多起床的
大学上课经常11点上最后一节课,准备着吃午饭
人为什么会把这种毫无关联的东西强加在自己身上呢!初恋是无罪的,可是孤独难过的时候却会深深的想着她,然后痛苦更加痛苦以致麻木。人孤独无依地生存在宇宙之中,创造各种事物情感来麻醉自己。人活着就是为了"有"、"欲望"。我也有欲望,但我知道那愿望却无法实现,所以会从另外一个角度看,会很冷静。哀兵必胜,大概是形容我这种人吧。对什么都不在乎了反而能获得一种洞察世界的心境——这或许是这些年来最大的收获。
周日去外面,一传教士走过来问我对圣经感兴趣吗...这种情况我已经遇到过很多次了。难道是主又派人来帮助我脱离苦海?有个幽默笑话是这样的:
一个人掉进水里快要淹死了,这时有只船过来问:"需要帮忙吗?"
他说:"不用,谢谢,上帝会来救我的"
后来又来了一只船,问:"需要帮忙吗?"
他说:"不用,谢谢,上帝会来救我的"
后来,他淹死了,去了天堂,问:"上帝啊,为什么你不救我?"
上帝说:"我不是派了两艘船去救你了吗?笨蛋"
一句"笨蛋"骂了多少人...而我却宁愿一直笨下去。
这,又有什么关系!