Chinaunix首页 | 论坛 | 博客
  • 博客访问: 155882
  • 博文数量: 41
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 425
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-14 10:16
文章分类
文章存档

2011年(1)

2010年(5)

2009年(35)

我的朋友

分类: LINUX

2009-10-09 10:40:52

tcp.c文件的tcp_write函数

978计划工作组 2009-10-9

1函数源码

/*

 *    This routine copies from a user buffer into a socket,

 *    and starts the transmit system.

 */

 

static int tcp_write(struct sock *sk, unsigned char *from,

         int len, int nonblock, unsigned flags)

{

       int copied = 0;

       int copy;

       int tmp;

       struct sk_buff *skb;

       struct sk_buff *send_tmp;

       unsigned char *buff;

       struct proto *prot;

       struct device *dev = NULL;

 

       sk->inuse=1;

       prot = sk->prot;

       while(len > 0)

       {

              if (sk->err)

              {                   /* Stop on an error */

                     release_sock(sk);

                     if (copied)

                            return(copied);

                     tmp = -sk->err;

                     sk->err = 0;

                     return(tmp);

              }

 

              /*

               *    First thing we do is make sure that we are established.

               */

      

              if (sk->shutdown & SEND_SHUTDOWN)

              {

                     release_sock(sk);

                     sk->err = EPIPE;

                     if (copied)

                            return(copied);

                     sk->err = 0;

                     return(-EPIPE);

              }

 

              /*

               *    Wait for a connection to finish.

               */

      

              while(sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT)

              {

                     if (sk->err)

                     {

                            release_sock(sk);

                            if (copied)

                                   return(copied);

                            tmp = -sk->err;

                            sk->err = 0;

                            return(tmp);

                     }

 

                     if (sk->state != TCP_SYN_SENT && sk->state != TCP_SYN_RECV)

                     {

                            release_sock(sk);

                            if (copied)

                                   return(copied);

 

                            if (sk->err)

                            {

                                   tmp = -sk->err;

                                   sk->err = 0;

                                   return(tmp);

                            }

 

                            if (sk->keepopen)

                            {

                                   send_sig(SIGPIPE, current, 0);

                            }

                            return(-EPIPE);

                     }

 

                     if (nonblock || copied)

                     {

                            release_sock(sk);

                            if (copied)

                                   return(copied);

                            return(-EAGAIN);

                     }

 

                     release_sock(sk);

                     cli();

             

                     if (sk->state != TCP_ESTABLISHED &&

                                sk->state != TCP_CLOSE_WAIT && sk->err == 0)

                         {

                            interruptible_sleep_on(sk->sleep);

                            if (current->signal & ~current->blocked)

                            {

                                   sti();

                                   if (copied)

                                          return(copied);

                                   return(-ERESTARTSYS);

                            }

                     }

                     sk->inuse = 1;

                     sti();

              }

 

       /*

        * The following code can result in copy <= if sk->mss is ever

        * decreased.  It shouldn't be.  sk->mss is min(sk->mtu, sk->max_window).

        * sk->mtu is constant once SYN processing is finished.  I.e. we

        * had better not get here until we've seen his SYN and at least one

        * valid ack.  (The SYN sets sk->mtu and the ack sets sk->max_window.)

        * But ESTABLISHED should guarantee that.  sk->max_window is by definition

        * non-decreasing.  Note that any ioctl to set user_mss must be done

        * before the exchange of SYN's.  If the initial ack from the other

        * end has a window of 0, max_window and thus mss will both be 0.

        */

 

       /*

        *    Now we need to check if we have a half built packet.

        */

 

              if ((skb = tcp_dequeue_partial(sk)) != NULL)

              {

                      int hdrlen;

 

                       /* IP header + TCP header */

                     hdrlen = ((unsigned long)skb->h.th - (unsigned long)skb->data)

                              + sizeof(struct tcphdr);

      

                     /* Add more stuff to the end of skb->len */

                     if (!(flags & MSG_OOB))

                     {

                            copy = min(sk->mss - (skb->len - hdrlen), len);

                            /* FIXME: this is really a bug. */

                            if (copy <= 0)

                            {

                                  printk("TCP: **bug**: \"copy\" <= 0!!\n");

                                  copy = 0;

                            }

        

                            memcpy_fromfs(skb->data + skb->len, from, copy);

                            skb->len += copy;

                            from += copy;

                            copied += copy;

                            len -= copy;

                            sk->write_seq += copy;

                     }

                     if ((skb->len - hdrlen) >= sk->mss ||

                            (flags & MSG_OOB) || !sk->packets_out)

                            tcp_send_skb(sk, skb);

                     else

                            tcp_enqueue_partial(skb, sk);

                     continue;

              }

 

     

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