代码笔记 | TCP 组包和拆包算法

 
/*************************************
文件名: server.c
TCP 组包和拆包实现算法
  
*/
#include 
#include 
#include 
#include 
#include 
#include 
  
  
#include 
#include 
#include 
  
  
  
#define BUF_SIZE 1024*5
  
  
//#define TCP_PACK_DEBUG 1
  
  
int main()
{
  
    int nBufuseLen=0;       //缓冲区里用到的长度
    int nRevOnceLen=0;      //read 一次读到的长度
    int nPackLen=0;         //每一包的长度,包括头和两个长度和尾字节
    int bufSize=BUF_SIZE;
  
  
    unsigned char buf[BUF_SIZE];     //read 的缓存
  
  
    int i=0;
  
  
    int sfp,nfp; /* 定义两个描述符 */
    struct sockaddr_in s_add,c_add;
    int sin_size;
    unsigned short portnum=6000; /* 服务端使用端口 */
    printf("Hello,welcome to my server !\\r\\n");
    sfp = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == sfp)
    {
        printf("socket fail ! \\r\\n");
        return -1;
    }
    printf("socket ok !\\r\\n");
    /* 填充服务器端口地址信息,以便下面使用此地址和端口监听 */
    bzero(&s_add,sizeof(struct sockaddr_in));
    s_add.sin_family=AF_INET;
    s_add.sin_addr.s_addr=htonl(INADDR_ANY); /* 这里地址使用全0,即所有 */
    s_add.sin_port=htons(portnum);
    /* 使用bind进行绑定端口 */
    if(-1 == bind(sfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
    {
        printf("bind fail !\\r\\n");
        return -1;
    }
    printf("bind ok !\\r\\n");
    /* 开始监听相应的端口 */
    if(-1 == listen(sfp,5))
    {
        printf("listen fail !\\r\\n");
        return -1;
    }
    printf("listen ok\\r\\n");
    //  while(1)
    {
  
  
        //    char buf[1027];
        //    int readlen;
  
  
        sin_size = sizeof(struct sockaddr_in);
        /* accept服务端使用函数,调用时即进入阻塞状态,等待用户进行连接,在没有客户端进行连接时,程序停止在此处,
           不会看到后面的打印,当有客户端进行连接时,程序马上执行一次,然后再次循环到此处继续等待。
           此处accept的第二个参数用于获取客户端的端口和地址信息。
            */
        nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size);
        if(-1 == nfp)
        {
            printf("accept fail !\\r\\n");
            return -1;
        }
        printf("accept ok!\\r\\nServer start get connect from %#x : %#x\\r\\n",ntohl(c_add.sin_addr.s_addr),ntohs(c_add.sin_port));
        /* 这里使用write向客户端发送信息,也可以尝试使用其他函数实现 */
        if(-1 == write(nfp,"hello,welcome to my server \\r\\n",32))
        {
            printf("write fail!\\r\\n");
            return -1;
        }
  
  
//头0xF9   两个长度字节   数据   尾0xF8
        while(1)
        {
#ifdef TCP_PACK_DEBUG
            {
                printf("bufSize = %d ,nBufuseLen = %d\\n",bufSize,nBufuseLen);
            }
#endif
            if(bufSize>nBufuseLen)
            {
                nRevOnceLen=read(nfp,buf+nBufuseLen,bufSize-nBufuseLen);
                nBufuseLen=nBufuseLen+nRevOnceLen;
  
  
#ifdef TCP_PACK_DEBUG
                {
                    printf("nBufuseLen = %d>3\\n",nBufuseLen);
                }
#endif
                /*
                                printf(" nRevOnceLen data:\\n");
                                for(i=0; i3)            //用到的大于3个字节
            {
  
  
                /*            printf(" nBufuseLen data:\\n");
                            for(i=0; i=nPackLen)                //大于和=
                    {
#ifdef TCP_PACK_DEBUG
                        {
                            printf("buf[nPackLen-1] = 0x%x \\n",buf[nPackLen-1]&0xFF);
                        }
#endif
  
  
                        if((buf[nPackLen-1]&0xFF)==0xF8)                  //尾
                        {
                            //找到一包数据,所有的数据都往前移动nPackLen个字节
#ifdef TCP_PACK_DEBUG
                            {
                                printf("head 0x%x length %d tail 0x%x \\n", buf[0]&0xFF,nPackLen,buf[nPackLen-1]&0xFF);
                            }
#endif
  
  
                            for(i=0; i

你可能感兴趣的:(算法,tcp,代码笔记,代码笔记)