分类: LINUX
2008-10-24 10:09:43
TCP是基于流的形式来读写数据。
同学需要在数据头加一个数据的大小,就是在TCP上加一层协议,呵呵,TCP包协议?
其实可以有SCTP协议吧?
不过,看了他实现的代码,看不懂,500行代码,组包,拆包,还有大量的memcpy。不过,佩服同学的编程能力,一个组包,拆包的程序如此快就出来了。
不过感觉效率有点低了,像我是追求代码效率的人,自己写了一个简单的,结果代码少的可怜,不到50行。
当然,如果没有对内核有一点了解,估计我得写个500+行了。
其实,socket里提供相当多的标志,可以简化很多东西。
一,发送时可以减小内存的copy
同学是提供一个函数,nb_send,不过在nb_send里malloc了一块内存,将数据的长度写进去,再将数据拷贝进去。
memcpy,这个是要避免的。
方法:针对申请/释放内存做特殊的处理,多申请4字节,
| 头 | ------ 数据 -------- |
void *tcp_malloc(int size)
{
return malloc(size + 4) + 4;
}
void *tcp_free(void *p)
{
free(p - 4);
}
这样,数据包的最头4个字节就可以用于存放长度,不用在nb_send里面申请内存再memcpy了。
只需要在发送TCP包时使用tcp_malloc/tcp_free来申请释放内存。
二,接收时可以不用copy
|长度|-----------数据----------|长度|-------数据------|长度|----------数据---------|
只有在接收到完整的一个数据包后才返回,数据缓冲区不够,要保证接收完数据包并丢掉。
以保证下一次接收时头4个字节是数据包的长度。
int nb_recv(int socket, void *buffer, size_t size, int flags)
{
上锁;//保证以下函数只能进入一次
int len;
接收数据包的长度(接收4个字节);
接收数据包长度的数据到buffer里面,如果buffer长度不够,要保证将数据接收完。
//现在,socket里缓冲的数据头是下一个数据包的长度
解锁;
}
具体的可以info recv。
想要写好代码,还得对你的平台由很深的了解,呵呵:)