• 2015-07-16

    经典的 TCP socket 读取报文错误

    Views: 31773 | 6 Comments

    面试了很多做了多年网络编程的人, 从TCP socket中读取报文这项基本技能, 许多人都做不对. 经典的错误用法是:

    char buf[1024]; // 1024或者更大
    read(sock, buf, sizeof(buf));
    if(parse(buf) == 1){
        // 报文解析完毕
    }else{
        // 不是一个完整的报文, 丢弃
    }
    

    这是非常经典的错误! 没有任何文档或者手册表明, read()会读到*完整*的报文, 对于read()函数来说, 它只知道字节流, 不知"报文"为何物. read()可能只读到了1个字节的数据就返回... 而且, read()返回的数据的长度, 和对方write()不是一一对应的. 对方调用1次write(), 可能本方要调用1次或者2次或者更多次read().

    这个错误之所以经典, 是因为在局域网条件下, 且报文非常小的情况下, 一般(仅仅是一般, 不是100%)write()和read()是一一对应的, 所以, 有些人即使是在BAT公司写了10年网络编程, 也发现不了这个错误. 这个错误就是所谓的"TCP粘包/断包".

    看看这个PDF: 高性能并发网络服务器设计与实现.pdf, 看看如何正确地从TCP socket中读取报文. 或者看看 Sim C++ 框架的源码, 了解下 Sim 是如何从 TCP socket 中读取一个报文: https://github.com/ideawu/sim/blob/master/src/server.cpp#L143

    Posted by ideawu at 2015-07-16 16:41:23
  • 2015-07-14

    iOS与PHP加密解密

    Views: 16770 | No Comments

    之前说过, iOS 的加密解密方法非常不方便, 不易于和 PHP 或者 Java 之间交互, 比较封闭.

    为了和PHP服务器端方便地进行加密解密操作, 我封装了 RSA 类. 使用这个类, 你可以用你喜欢的工具, 如 openssl 命令行, PHP 脚本, 生成友好的公钥或者私租文本, 然后 iOS 使用这些密钥进行加密, PHP 进行解密, 或者 PHP 进行解密, 由 iOS 进行解密.

    方法如下:

    // return base64 encoded string
    + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
    // return raw data
    + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey;
    // TODO:
    //+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey;
    //+ (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privKey;
    
    // decrypt base64 encoded string, convert result to string(not base64 encoded)
    + (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey;
    + (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey;
    // TODO:
    //+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
    //+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey;
    

    目前能实现:

    1. iOS 用公钥加密, PHP 用私钥解密
    2. PHP 用私钥加密, iOS 用公钥解密
    3. iOS 用私钥加密, PHP 用公钥解密(未实现)
    4. PHP 用公钥加密, iOS 用私钥解密(未实现)

    后面两种场景的需求还未实现, 但很快会实现. 欢迎你来补充. 项目地址: https://github.com/ideawu/Objective-C-RSA

    Posted by ideawu at 2015-07-14 16:59:51 Tags:
  • 2015-06-19

    iOS 正确接收 HTTP chunked 数据的方法

    Views: 18046 | 1 Comment

    iOS 上的 NSURLConnection 一般能处理绝大部分的 HTTP 请求场景, 不过, 对于一种情况, 它无法处理, 那便是接收 HTTP chunked data. NSURLConnectionDataDelegate 有一个方法, 可以在读取到部分响应时进行回调, 但是, 数据不是按 HTTP chunked data 来接收的, 它会将多个 chunk 合并到一起.

    @protocol NSURLConnectionDataDelegate 
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
    @end
    

    没办法, 只能使用 cURL for iOS, 在 iComet 的 iOS 例子里有介绍.

    首先, 下载 cURL for iOS: http://seiryu.home.comcast.net/~seiryu/libcurl-ios.html

    然后, 把里面的 libcurl.a 引入你的项目, 还要把它的头文件引入. 注意, cURL 依赖 libz.dylib.

    Continue reading »

    Posted by ideawu at 2015-06-19 19:54:21
  • 2015-06-17

    iOS流式布局UI框架CocoaUI开源

    Views: 14847 | 1 Comment

    CocoaUI 是一个强大的 iOS UI 框架, 使用 Web 开发者熟悉的 HTML+CSS 流式布局方式, 轻松地开发 iOS 原生 App 的界面.

    CocoaUI 的特性主要包括:

    • 高效的原生界面, 非低效的 WebView 控件方式
    • 自适应(Adaptive)动态流式布局, 轻松适配多种屏幕尺寸
    • 采用简洁高效的 HTML+CSS 语法定义布局(Layout)和展现(Appearance)

    Continue reading »

    Posted by ideawu at 2015-06-17 17:50:00 Tags:
  • 2015-05-18

    简单的 C++ 网络服务框架 Sim 介绍

    Views: 23969 | 5 Comments

    可测性

    Sim 采用了一种极简的报文格式, 在你没有开始写 Client 时, 你就可以利用手上现成的工具, 如 nc, telnet 来测试. 可测性非常重要, 你可以随时查看代码的执行效果, 这对开发者的心理会产生非常正面的促进作用. 即使你不想使用 nc 这样的命令, 你想写 PHP 或者 Python 脚本, 也是非常简单的.

    例如, 你采用 Sim 框架写了一个计算加法的服务器. 这时怎么测试呢? 很简单! 在命令行执行

    $ nc 127.0.0.1 8800
    add 1 3
    ok 4
    

    随时随地地通过实际的输入和输出来测试程序, 会让程序员的心理更愉悦. 如果通过枯燥的单元测试, 进行大量参数配置, 只会让人心慌, 影响开发效率.

    内置 Log/Config 工具

    Sim 采用了 SSDB 项目的日志和配置代码, 让你的服务器立即就拥有日志输出功能和可配置性. 日志非常重要, 我几乎不使用 gdb 这样底层的调试工具. 有了 Config, 像修改端口这样的简单需求, 就不用再修改代码重新编译了.

    进程管理

    Sim 提供的工具可以让你的程序启动为后台进程, 不用借助 supervisor, nohup 这样的额外工具.

    关于性能

    记住, 不要一开始就关心性能, 计算机和 C++ 比你相像的要快得多!

    其它

    Sim 完全开源, 基于 New BSD 协议.

    项目地址: https://github.com/ideawu/sim

    Posted by ideawu at 2015-05-18 17:22:10
  • 2015-05-15

    MySQL 在线增加从库

    Views: 12741 | 2 Comments

    Master

    创建用户:

    GRANT REPLICATION SLAVE ON *.* TO 'userx'@'server_b' IDENTIFIED BY 'xxxxx';
    

    导出数据:

    mysqldump --all-databases --master-data > dbdump.sql
    

    导致的 dbdump.sql 里会包含 binlog 的位置.

    Slave

    CHANGE MASTER TO MASTER_HOST='server_a';
    CHANGE MASTER TO MASTER_USER='userx';
    CHANGE MASTER TO MASTER_PASSWORD='xxxxx';
    CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=106;
    start slave;
    show slave status\G
    
    Posted by ideawu at 2015-05-15 10:14:21
|<<<242526272829303132>>>| 28/138 Pages, 825 Results.