LWIP之七SOCKET编程

LWIP之七SOCKET编程
LWIP之七SOCKET编程

LWIP之SOCKET编程

2009-05-16 00:46:28

标签:

原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明。否则将追究法律责任。https://www.360docs.net/doc/717705542.html,/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;

https://www.360docs.net/doc/717705542.html,_sec = 1;

https://www.360docs.net/doc/717705542.html,_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”博客,请务必保留此出处https://www.360docs.net/doc/717705542.html,/214870/158419

相关主题
相关文档
最新文档