LWIP之SOCKET编程
精选 转载原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://bluefish.blog.51cto.com/214870/158419
2009-05-15 LWIP之SOCKET编程
前几天看了关于LWIP协议栈的实现和FREERTOS的基本原理。今天开始调试LWIP的socket通信,是基于freertos系统的ARM9_STR91X_IAR开发板。
这是个现成的实例,由于lwip已经由freertos移植好了,而调试的目的就是实现在lwip上的socket通信。本来以为很容易的问题,结果还是搞了一天,当然和EWARM工具的难用也还是有很大关系的。
首先要注意的一点是sys_thread_new和xTaskCreate的区别。我们知道xTaskCreate是用来创建一个task任务的。类似于windows下的process。
/*
Starts a new thread with priority "prio" that will begin its execution in the
function "thread()". The "arg" argument will be passed as an argument to the
thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent.
*/
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
{
xTaskHandle CreatedTask;
int result;
result = xTaskCreate(thread, ( signed portCHAR * ) s_sys_arch_state.cTaskName, s_sys_arch_state.nStackDepth, arg, prio, &CreatedTask );
// For each task created, store the task handle (pid) in the timers array.
// This scheme doesn't allow for threads to be deleted
timeoutlist[nextthread++].pid = CreatedTask;
if(result == pdPASS)
{
++s_sys_arch_state.nTaskCount;
return CreatedTask;
}
else
{
return NULL;
}
}
很显然,sys_thread_new最终对task的创建也是通过xTaskCreate来实现的。但是请注意不同点,前者会把新创建的task的pid放入到一个timeoutlist的链表中。
起初我也没有主要这个小问题,直到用socket系列函数的select的时候,一直过不去,而是abort中断了,具体原因请看select函数实现,其中sys_arch_timeouts的调用就是获取当前task的timeout,如果没有用sys_thread_new创建的话,这里就没有我用来调用select的当前task,所以就有了以后的abort中断了。
下面给一个socket编程的实现
static void vLWIPSendTask( void *pvParameters )
{
int listenfd;
int remotefd;
int len;
struct sockaddr_in local_addr,remote_addr;
fd_set readset;
fd_set writeset;
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
//struct lwip_socket* sock;
listenfd = socket(AF_INET,SOCK_STREAM,0);
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(80);
local_addr.sin_len = sizeof(local_addr);
local_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(listenfd, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0)
{
return ;
}
if (listen(listenfd, 1) == -1)
{
return;
}
len = sizeof(remote_addr);
while(1)
{
//这里注意一下,lwip的阻塞不是在listen函数,而是accept
remotefd = accept(listenfd, (struct sockaddr *)&remote_addr, &len);
//close(listenfd);
//listenfd = -1;
//getpeername(remotefd, (struct sockaddr *)&remote_addr, &len);
if(remotefd != -1)
{
int ret;
send(remotefd,"start to work!\r\n",16,0);
for(;;)
{
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(remotefd, &readset);
FD_SET(remotefd, &writeset);
ret = lwip_select(remotefd+1, &readset, &writeset, 0, &timeout);
if(ret > 0)
{
if (FD_ISSET(remotefd, &readset))
{
memset(buf,0,50);
if(recv(remotefd,buf,50,0) <= 0)
{
close(remotefd);
remotefd = -1;
break;
}
else
{
int i = strlen(buf);
send(remotefd,buf,i ,0);
}
}
/*
else if(FD_ISSET(remotefd, &writeset))
{
send(remotefd,"this is time to send!\r\n",25,0);
}
*/
}
else if(ret < 0)
{
close(remotefd);
remotefd = -1;
break;
}
}
}
}
vTaskDelete( NULL );
}
对的,这是作为server端实现的,可以和通用的socket客户端配。经过测试至少可以与windows上的socket程序匹配(接收,发送数据)。
本文出自 “bluefish” 博客,请务必保留此出处http://bluefish.blog.51cto.com/214870/158419
上一篇:LWIP的底层结构(物理层)
下一篇:我的友情链接
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
linux之socket编程
linux之socket编程
数据 端口号 IP -
LWIP之SOCKET编程
LWIP协议栈学习七
职场 休闲 -
LWIP之SOCKET的实现
LWIP协议栈学习一
职场 休闲 lwip -
LWIP应用开发|Socket API编程模型
Socket API编程模型
tcp udp socket lwip lan8720 -
LWIP应用开发|Socket API编程优化
Socket API编程优化
socket lwip stm32cubemx 文件描述符 客户端 -
TCP/IP之socket编程
socket编程
编程 socket