Chinaunix首页 | 论坛 | 博客
  • 博客访问: 212756
  • 博文数量: 37
  • 博客积分: 3082
  • 博客等级: 中校
  • 技术积分: 387
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-14 13:59
文章分类
文章存档

2013年(1)

2012年(1)

2011年(2)

2010年(7)

2009年(1)

2008年(13)

2007年(12)

我的朋友

分类: 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。

想要写好代码,还得对你的平台由很深的了解,呵呵:)

阅读(2361) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~