socket.c

 
/*
*********************************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*
*                                           (c) Copyright 2011
*                                           All Rights Reserved
*
* File : socket.c
* By   : Weekope Chou
*********************************************************************************************************
*/

#include "socket.h"
#include "ucos_ii.h"

INT32S sockFD = -1;

Socket clientSockets[10];  
INT32S clientIndex = -1;  

/*
  Socket_Create() Socket_Bind() Socket_Listen()三个函数必须同时依次使用,客户端建立套接字时需要绑定操作
*/
                                                                                                              
/*
*********************************************************************************************************
*                                             Create Socket
*
* Description: This function create Socket with specified domain、type and protocol. 
*
* Arguments  : domain     is a flag for a group of IP
*
*              type       defines the type of data
*     
*              protocol   defines the protocol to be used
*
* Returns    : sockFD     Socket descriper
*********************************************************************************************************
*/
INT32U Socket_Create(INT16U domain, INT32U type, INT32U protocol){
   
   //Initiate Socket array only when there is no Socket created
 if(sockFD == -1){
     INT32U arrayIndex = 0;
  
  //Create arraySocket with all elements initiated
     ip_addr iniSrcAddr;
     ip_addr iniDesAddr;
  Mbuf * iniSendBuff;
     Mbuf * iniRcvBuff;
  TCP_tcb * iniTcb;
     
  //Initiate Socket
  Socket iniSocket;   
     iniSocket.domain = 0;
     iniSocket.sockFD = -1;
      iniSocket.type = 0;
  iniSocket.protocol = 0;
     iniSocket.srcPort = 0;
     iniSocket.desPort = 0;
     iniSocket.srcAddr = iniSrcAddr;
     iniSocket.desAddr = iniDesAddr;
     iniSocket.sendbuf = iniSendBuff;
     iniSocket.rcvbuf = iniRcvBuff;
     //iniSocket.sin_zero;
     iniSocket.s_tcb = iniTcb;

     for(arrayIndex; arrayIndex < 10; arrayIndex++){
          arraySocket[arrayIndex] = iniSocket;
     }
      
 }
 
    //Create Socket
 sockFD++;
 arraySocket[sockFD].domain = domain;
 arraySocket[sockFD].type = type;
 arraySocket[sockFD].protocol = protocol;

 //Return sockFD as descriper
 return sockFD;

}


/*
*********************************************************************************************************
*                                             Bind Socket
*
* Description: This function binds local Socket with sockFD. 
*
* Arguments  : sockFD     local Socket descriper
*
*              p_thisAddr local Socket
*
*              addrLen    size of Socket
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_Bind(INT32U sockFD, Socket * p_thisAddr, INT32U addrLen){
    
 //Bind sockFD with Socket
 arraySocket[sockFD].sockFD = sockFD;
 
 //Binding successful
 return SUCCESSFUL;
 
}


/*
*********************************************************************************************************
*                                         Setup Listen Socket
*
* Description: This function setups Listen Socket and wait for connection request. 
*
* Arguments  : sockFD     local Socket descriper
*
*              backLog    request array lenth
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_Listen(INT32U serverFD, INT32U backLog){     //Listen sockFD不可变
                  //在主模块中需要创建常量保存服务器sockFD,并赋值Listen
 Socket * clientSocket;         //serverFD = Socket_Create()
 Mbuf * p_mbuf;
 clientSocket = &clientSockets[clientIndex];
 p_mbuf->m_socket = clientSocket;                     
 
 //Create connection
 if(syn){
     syn = 0;

  //Get SYN diagram and send back ACK+SYN diagram
  clientSocket->s_tcb->tt_controlbit = ACK | SYN;
  TCP_Output(p_mbuf);         

  while(1){
      //Wait for ACK diagram
   OSTimeDlyHMSM(0,0,1,0);
 
   //TCP connection has been done
      if(ack){
       ack = 0;
          
       //Compare requesting Socket with listening Socket
    if(arraySocket[sockFD].srcAddr.s_addr == clientSocket->srcAddr.s_addr && arraySocket[sockFD].srcPort == clientSocket->srcPort){
        listenConfirm = 1;
     return SUCCESSFUL;
    }
   }
          
  }  
 }

 //Close connection
 if(fin){
     fin = 0;
  
  //Get FIN diagram and send back ACK diagram and FIN diagram
  clientSocket->s_tcb->tt_controlbit = ACK;
  TCP_Output(p_mbuf);
  clientSocket->s_tcb->tt_controlbit = FIN;
  TCP_Output(p_mbuf);
  
        while(1){
      //Wait for ACK diagram
   OSTimeDlyHMSM(0,0,1,0);

   if(ack){
       ack = 0;
    return SUCCESSFUL;
      }
  }  
 }

 return FAILED;

}


/*
*********************************************************************************************************
*                                         Send Connection Request
*
* Description: This function sends connection request. 
*
* Arguments  : sockFD        local Socket descriper
*
*              p_serverAddr  server Socket
*
*              addrLen       size of Socket 
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_Connect(INT32U sockFD, Socket * p_serverSocket, INT32U addrLen){  
    
 Mbuf * p_mbuf;
 
 //Put client Socket into clientSockets[]
    clientIndex++;
 clientSockets[clientIndex] = arraySocket[sockFD];
 
 //Send SYN diagram
 p_mbuf->m_socket = p_serverSocket;
 p_serverSocket->s_tcb->tt_controlbit = SYN;
 TCP_Output(p_mbuf);

 while(1){
     //Wait for ACK+SYN diagram
     OSTimeDlyHMSM(0,0,1,0);

     //Wait until get ACK+SYN diagram
     if(ackAndsyn){
            ackAndsyn = 0;

         //Get ACK+SYN diagram and send back ACK diagram
      p_serverSocket->s_tcb->tt_controlbit = ACK;
      TCP_Output(p_mbuf);
            
      return SUCCESSFUL;
     }    
 }

}


/*
*********************************************************************************************************
*                                         Accept Connection Request
*
* Description: This function accept connection request and save client's Socket. 
*
* Arguments  : sockFD        local Socket descriper
*
*              p_serverAddr  server Socket
*
*              addrLen       size of Socket 
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_Accept(INT32U sockFD, Socket * newSocket, INT32U * addrLen){
    
 if(1){    //我不知道什么条件失败,呵呵
     
  //Get client Socket
  newSocket = &clientSockets[clientIndex];
  
  return SUCCESSFUL;

 }
 
 else return FAILED;  
   
}


/*
**************************************************************
*
*   考虑缓冲区长度和发送接受数据大小之间的关系
*
**************************************************************
*/

/*
*********************************************************************************************************
*                                         Send TCP Data
*
* Description: This function sends TCP data. 
*
* Arguments  : sockFD        local Socket descriper
*
*              p_sendSocket  Socket contains data to be transmitted
*
*              len           size of data
*
*              flags         Socket flag 
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_Send(INT32U sockFD, Socket * p_sendSocket, INT32U len, INT8U flags){
    
 //See if p_sendBuff.sendBuff.socket points to p_sendBuff, that is whether Socket and Mbuf connected to each other
 if(sockFD == p_sendSocket->sendbuf->m_socket->sockFD){    
     
  //Get data from p_sendSocket and transmit pointer of data to TCP
     TCP_Output(p_sendSocket->sendbuf);

  return SUCCESSFUL;

 }

 else return FAILED;

}


/*
*********************************************************************************************************
*                                         Recieve TCP Data
*
* Description: This function recieves TCP data. 
*
* Arguments  : sockFD        local Socket descriper
*
*              buff          point to data to be recieved
*
*              len           size of buffer
*
*              flags         Socket flag 
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_Recv(INT32U sockFD, void * buff, INT32U len, INT8U flags){
 
    if(1){             //我不知道什么条件失败,呵呵
     
  //Get data and put into buff
  arraySocket[sockFD].rcvbuf = arraySocket[sockFD].rcvbuf->m_hdr.mh_nextpkt;
  Mbuf_GetData(&arraySocket[sockFD].rcvbuf,buff,SIZE_OF_DHCPMES); 
  
  return SUCCESSFUL;
   
 }
 
 else return FAILED;        

}


/*
*********************************************************************************************************
*                                         Send UDP Data
*
* Description: This function sends UDP data. 
*
* Arguments  : sockFD        local Socket descriper
*
*              p_sendSocket  Socket of sender
*
*              len           size of data
*
*              flags         Socket flag
*
*      p_to          Socket of reciever
*
*       toLen         size of Socket
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_SendTo(INT32U sockFD, Socket * p_sendSocket, INT32U len, INT8U flags, Socket * p_to, INT32U toLen){

    //See if p_sendBuff.sendBuff.socket points to p_sendBuff, that is whether Socket and Mbuf connected to each other
 if(p_to->sockFD == p_to->sendbuf->m_socket->sockFD){    
     
  //Get source/destination ip/port and data,invoke UDP interface to transmit data
        UDP_Output(&arraySocket[sockFD], p_sendSocket->sendbuf, p_to->sendbuf, 0);
  
  return SUCCESSFUL;
   
 }

 else return FAILED;
    
}


/*
*********************************************************************************************************
*                                         Recieve UDP Data
*
* Description: This function recieves UDP data. 
*
* Arguments  : sockFD        local Socket descriper
*
*              buff          point to data to be recieved
*
*              len           size of data
*
*              flags         Socket flag
*
*      p_to          Socket of reciever
*
*       toLen         size of Socket
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_RecvFrom(INT32U sockFD, void * buff, INT32U len, INT8U flags, Socket * p_from, INT32U fromLen){
    
 if(1){       //我不知道什么条件失败,呵呵

     //Get data and put into buff
  arraySocket[sockFD].rcvbuf = arraySocket[sockFD].rcvbuf->m_hdr.mh_nextpkt;
  Mbuf_GetData(&arraySocket[sockFD].rcvbuf,buff,SIZE_OF_DHCPMES); 
  
  return SUCCESSFUL; 

 }
 
 else return FAILED;     

}


/*
*********************************************************************************************************
*                                         Close Socket
*
* Description: This function closes Socket. If type is SOCKET_STREAM, Socket will be closed and 
*
*              TCP connection will be shutdowned. If type is SOCKET_STREAM, only Socket will be closed. 
*
* Arguments  : sockFD        local Socket descriper
*
* Returns    : ==1       successful
*
*              ==0        failed
*********************************************************************************************************
*/
INT8U Socket_Close(INT32U sockFD){             //此程序中需要由客户端发起关闭请求
 
 ip_addr iniSrcAddr;
 ip_addr iniDesAddr;
    Mbuf * iniSendBuff;
    Mbuf * iniRecvBuff;
 TCP_tcb * iniTcb;

 Socket desSocket;

    INT32U numSocket = 0;

 //Release both server and client Socket
 for(numSocket; numSocket < 2; numSocket++){
     arraySocket[sockFD].domain = 0;
     arraySocket[sockFD].sockFD = -1;
     arraySocket[sockFD].type = 0;
     arraySocket[sockFD].protocol = 0;
     arraySocket[sockFD].srcPort = 0;
  arraySocket[sockFD].desPort = 0;
     arraySocket[sockFD].srcAddr = iniSrcAddr;
     arraySocket[sockFD].desAddr = iniDesAddr;
     arraySocket[sockFD].sendbuf = iniSendBuff;
     arraySocket[sockFD].rcvbuf = iniRecvBuff;
     arraySocket[sockFD].sin_zero;
     arraySocket[sockFD].s_tcb = iniTcb;
  
  sockFD--;
 }    
 
 //SOCKET_STREAM should shutdown TCP connection
 if(arraySocket[sockFD].type == SOCKET_STREAM){
     
  //Find server Socket
  if(arraySocket[sockFD + 1].sockFD == -1){
       desSocket = arraySocket[sockFD - 1];
  }
  else desSocket = arraySocket[sockFD + 1];

  //Send FIN diagram
     desSocket.s_tcb->tt_controlbit = FIN;
  TCP_Output(desSocket.sendbuf);

        while(1){
      //Wait for ACK diagram and FIN diagram
   OSTimeDlyHMSM(0,0,1,0);
 
   //Wait until get FIN diagram
   if(ack && fin){
       ack = 0;
    fin = 0;

    //Send ACK diagram
          desSocket.s_tcb->tt_controlbit = ACK;
          TCP_Output(desSocket.sendbuf);
    
    //Clear current client Sockets from clientSockets[]
             clientIndex--;

    return SUCCESSFUL;    
   }
  }
  
 }

 //Clear current client Sockets from clientSockets[]
 clientIndex--;

 return SUCCESSFUL;
  
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值