📄 socket.c
字号:
/*
+FHDR------------------------------------------------------------------
Copyright (c),
Tony Yang –51,AVR,ARM firmware developer
Contact:qq 292942278 e-mail:tony_yang123@sina.com.cn
Abstract:
$Id: socket.c,v 1.9 2006/12/31 16:05:25 tony Exp $
-FHDR-------------------------------------------------------------------
*/
#include "config.h"
#include "tcp_ip_cfg.h"
#include "hardware.h"
#include "ethernet.h"
#include "uart0\uart0.h"
#include "ftp_cfg.h"
#include "icmp.h"
#include "arp.h"
#include "udp.h"
#include "tcp.h"
u16 cur_handle_position = 0;
/****************************************************************************
* 名称:socket
* 功能:获得一个空SOCKET
* 入口:protocol--SOCKET类型-(UDP_PROTOCOL 或TCP_PROTOCOL)
* 出口: 返回一个指向空SOCKET的指针,or NULL(failed)
****************************************************************************/
SOCKET * socket(u16 af,u16 type,u16 protocol)
{ u16 i;
if(protocol == UDP_PROTOCOL)
{
for(i = 0;i < MAX_UDP_LINKS;i++)
{
if(!UDP_Socket[i].EN)
break;
}
if(i >= MAX_UDP_LINKS)
return(NULL);
UDP_Socket[i].EN = 1;
UDP_Socket[i].PROTOCOL = UDP_PROTOCOL;
return(&UDP_Socket[i]);
}
else if(protocol == TCP_PROTOCOL)
{
for(i = 0;i < MAX_TCP_LINKS;i++)
{
if(!TCP_Socket[i].EN)
break;
}
if(i >= MAX_TCP_LINKS)
return(NULL);
TCP_Socket[i].EN = 1;
TCP_Socket[i].PROTOCOL = TCP_PROTOCOL;
TCP_Socket[i].type = type;
return(&TCP_Socket[i]);
}
return(NULL);
}
/****************************************************************************
* 名称:bind()
* 功能:将IP地址与SOCKET绑定
* 入口:sock--指向SOCKET的指针
struct sockaddr--包括IP地址和端口号
len --无作用
* 出口: SUCC
****************************************************************************/
u16 bind(SOCKET * sock,struct sockaddr * address,u8 len)
{
sock->SRC_IP_Address[0] = address->sin_addr[0];
sock->SRC_IP_Address[1] = address->sin_addr[1];
sock->SRC_IP_Address[2] = address->sin_addr[2];
sock->SRC_IP_Address[3] = address->sin_addr[3];
sock->SRC_Port[0] = address->sin_port & 0xff;
sock->SRC_Port[1] = address->sin_port >> 8;
return(SUCC);
}
/****************************************************************************
* 名称:listen()
* 功能:起动监听
* 入口:sock--指向SOCKET的指针
QTY --无作用
* 出口: SUCC
****************************************************************************/
u16 listen(SOCKET * sock, u16 QTY)
{
u16 port;
port = sock->SRC_Port[0] + sock->SRC_Port[1] * 256;
if(sock->PROTOCOL == UDP_PROTOCOL)
{
enable_a_port_listen(port);
}
else if(sock->PROTOCOL == TCP_PROTOCOL)
TCP_enable_a_port_listen(port);
return(SUCC);
}
/****************************************************************************
* 名称:connect()
* 功能:客户端连接服务器
* 入口:sock--指向SOCKET的指针
* struct sockaddr address--服务器的地址和监听端口号
* len --无作用(保留为将来扩展使用)
* 出口: 返回SUCC--连接成功 或者-FAIL
****************************************************************************/
u16 connect(SOCKET * sock, struct sockaddr * sevaddr,u8 len)
{
u8 IP[8];
u8 pkt[100],i;
u16 index,retry;
//u16 port;
//port = Allocate_A_LOCAL_Port();
// if(port == 0xffff)
// return(0xffff);
for(i = 0;i < 4;i++)
{
IP[i+4] = sock->SRC_IP_Address [i];
IP[i] = sevaddr->sin_addr[i];
sock->DEST_IP_Address[i] = sevaddr->sin_addr[i];
}
pkt[12] = sock->SRC_Port[1];
pkt[13] = sock->SRC_Port[0];
pkt[14] = sevaddr->sin_port >>8;
pkt[15] = sevaddr->sin_port & 0xff;
sock->DEST_Port[0] = sevaddr->sin_port & 0xff;
sock->DEST_Port[1] = sevaddr->sin_port >> 8;
index = sock - TCP_Socket;
retry = 0;
do{
if( Send_TCP_SYN_nACK(pkt+12,20,IP,index) == SUCC)
{
SendByte('c');SendByte('c');SendByte('c');SendByte('c');
return(index);
}
else
{SendByte('e');SendByte('e');SendByte('e');SendByte('e');
retry ++;
if(retry == 3)
return(0xffff);
}
}while(1);
}
/****************************************************************************
* 名称:listen()
* 功能:起动监听
* 入口:sock--指向SOCKET的指针
struct sockaddr * address,iii --无作用
* 出口: 返回SOCKET的索引号
****************************************************************************/
u16 accept(SOCKET * sock,struct sockaddr * address,u16 *iii)
{
u8 flag,j;
s16 i;
i = cur_handle_position;
while(1){
i++;
if(i>=MAX_TCP_LINKS)
i = 0;
if(i == cur_handle_position)
{cur_handle_position++;
if(cur_handle_position == MAX_TCP_LINKS)
cur_handle_position = 0;
return(0xffff);}
//for(i = MAX_TCP_LINKS - 1;i >= 0 ;i--)
//{
if(sock == (TCP_Socket + i))
continue;
if(TCP_Socket[i].EN)
{ /*检查源端口号*/
if(TCP_Socket[i].SRC_Port[1] == sock->SRC_Port[1] &&
TCP_Socket[i].SRC_Port[0] == sock->SRC_Port[0])
{/*检查源IP地址*/
flag = SUCC;
for(j = 0;j < 4;j++)
{
if(sock->SRC_IP_Address[j] != TCP_Socket[i].SRC_IP_Address[j])
{
flag = FAIL;
break;
}
}
if(flag == SUCC)
{
for(j = 0;j < 4;j++)
{
if(TCP_Socket[i].DEST_IP_Address[j] != 0)
{
flag = FAIL;
break;
}
}
if(flag == SUCC)
continue;
if(TCP_Socket[i].status == Closed)
{
TCP_Socket[i].status = Link_established;
{cur_handle_position = i;return(i);}
}
else if(TCP_Socket[i].status == Data_Transmition_State)
{cur_handle_position = i;return(i);}
else if(Query_Queue_data_available(&TCP_Socket[i]) > 0)
{cur_handle_position = i;return(i);}
else
continue;
}
else
{
continue;
}
}
else
continue;
}
}
return(0xffff);
}
/****************************************************************************
* 名称:recv()
* 功能:从socket读取数据
* 入口:handle--SOCKET的索引号
rec_buff--缓冲区的首地址
len-缓冲区长度
i --无作用
* 出口: 返回
****************************************************************************/
u16 recv(u16 handle,u8 * rec_buff,u16 len,u16 i)
{
u16 qty;
qty = Query_Queue_data_available(&TCP_Socket[handle]);
if(qty == 0)
return(0);
if(len > qty)
len = qty;
Queue_GET(&TCP_Socket[handle],rec_buff,len);
return(len);
}
/****************************************************************************
* 名称:send()
* 功能:向socket写入数据
* 入口:handle--SOCKET的索引号
rec_buff--缓冲区的首地址
len-缓冲区长度
i --无作用
* 出口: 返回
****************************************************************************/
u8 send(u16 handle,u8 *rec_buff,u16 len,u16 i)
{
//u16 retry;
struct _pkst TxdData;
TxdData.STPTR = NULL;
TxdData.length = len ;
TxdData.DAPTR =rec_buff;
/*retry = 0;
do{
if(Send_TCP_PSH(&TxdData, handle) == SUCC)
break;
retry++;
if( retry > 10)
return(FAIL);
}while(1);*/
Send_TCP_PSH(&TxdData, handle) ;
return(SUCC);
}
/****************************************************************************
* 名称:close()
* 功能:关闭一个SOCKET监听
* 入口:handle--SOCKET的索引号
* 出口: 返回
****************************************************************************/
void close(u16 handle)
{
if(TCP_Socket[handle].EN)
{
TCP_Socket[handle].status = Half_closed;
Send_TCP_FIN(handle);
}
}
/****************************************************************************
* 名称:recvform()
* 功能:从socket读数据(for UDP数据报)
* 入口:handle--SOCKET的索引号
rec_buff--缓冲区的首地址
len-缓冲区长度
* 出口: 返回
****************************************************************************/
u16 recvfrom(SOCKET *sock,u8 *rec_buff,u16 len,u8 i,struct sockaddr * address,u16 *addr_len)
{
u16 data_available;
if(sock->PROTOCOL == UDP_PROTOCOL)
{
sock->DEST_IP_Address[0] = address->sin_addr[0];
sock->DEST_IP_Address[1] = address->sin_addr[1];
sock->DEST_IP_Address[2] = address->sin_addr[2];
sock->DEST_IP_Address[3] = address->sin_addr[3];
sock->DEST_Port[0] = address->sin_port & 0xff;
sock->DEST_Port[1] = address->sin_port >> 8;
data_available = Query_Queue_data_available(sock);
if(len > data_available)
len = data_available;
if(len > 0)
Queue_GET(sock,rec_buff,len);
return(len);
}
return(SUCC);
}
/****************************************************************************
* 名称:send()
* 功能:向socket写入数据(for UDP数据报)
* 入口:handle--SOCKET的索引号
rec_buff--缓冲区的首地址
len-缓冲区长度
* 出口: 返回
****************************************************************************/
u16 sendto(SOCKET *sock,u8 *rec_buff,u16 len,u8 i,struct sockaddr * address,u16 *addr_len)
{
struct _pkst TxdData;
if(sock->PROTOCOL == UDP_PROTOCOL)
{
sock->DEST_IP_Address[0] = address->sin_addr[0];
sock->DEST_IP_Address[1] = address->sin_addr[1];
sock->DEST_IP_Address[2] = address->sin_addr[2];
sock->DEST_IP_Address[3] = address->sin_addr[3];
sock->DEST_Port[0] = address->sin_port & 0xff;
sock->DEST_Port[1] = address->sin_port >> 8;
TxdData.STPTR = NULL;
TxdData.length = len;
TxdData.DAPTR = rec_buff;
Send_UDP_PKT(&TxdData,sock);
}
return(len);
}
/*
+FFTR--------------------------------------------------------------------
$Log: socket.c,v $
Revision 1.9 2006/12/31 16:05:25 tony
增加了WEB服务器的功能,运行效果好
Revision 1.8 2006/12/31 23:03:39 tony
解决了DATA abort的bug,是由ftp.c调用函数accept造成的,因此给其加入一个循环,直到accept()返回值不为0xffff,结束
Revision 1.7 2006/12/31 17:49:37 tony
解决了写小文件的hang问题,但有data_abort错误,待解决
Revision 1.6 2006/12/31 16:09:00 tony
由于write_file慢(1KB/S)导致FTP服务器put file失序,不写file时序正常
Revision 1.5 2007/01/01 00:11:31 tony
完成了与FTP.EXE兼容,如命令dir,ls,get;
与IE(Internet Explorer)已完成了目录查看,
拷贝小于80k的文件
Revision 1.4 2007/01/01 14:53:47 tony
FTP 实现了拷贝文件的功能,
Revision 1.3 2006/12/31 16:12:54 tony
SOCKET API函数connect()测试成功
Revision 1.2 2006/12/31 16:04:53 tony
增加FTP代码,SOCKET_status字段
-FFTR--------------------------------------------------------------------
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -