LWIP UDP socket编程 可以指定本地端口号及发送长度不能太长问题分析
2017-08-08 15:13
501 查看
LWIP UDP socket编程 可以指定本地端口号及发送长度不能太长问题分析
<div class="article_manage clearfix"> <div class="article_r"> <span class="link_postdate">2016-03-01 17:02</span> <span class="link_view" title="阅读次数">913人阅读</span> <span class="link_comments" title="评论次数"> <a href="#comments" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(0)</span> <span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" onclick="javascript:collectArticle('LWIP+UDP+socket%e7%bc%96%e7%a8%8b+%e5%8f%af%e4%bb%a5%e6%8c%87%e5%ae%9a%e6%9c%ac%e5%9c%b0%e7%ab%af%e5%8f%a3%e5%8f%b7%e5%8f%8a%e5%8f%91%e9%80%81%e9%95%bf%e5%ba%a6%e4%b8%8d%e8%83%bd%e5%a4%aa%e9%95%bf%e9%97%ae%e9%a2%98%e5%88%86%e6%9e%90','50773942');return false;" title="收藏" target="_blank">收藏</a></span> <span class="link_report"> <a href="#report" onclick="javascript:report(50773942,2);return false;" title="举报">举报</a></span> </div> </div> <style type="text/css"> .embody{ padding:10px 10px 10px; margin:0 -20px; border-bottom:solid 1px #ededed; } .embody_b{ margin:0 ; padding:10px 0; } .embody .embody_t,.embody .embody_c{ display: inline-block; margin-right:10px; } .embody_t{ font-size: 12px; color:#999; } .embody_c 4000 { font-size: 12px; } .embody_c img,.embody_c em{ display: inline-block; vertical-align: middle; } .embody_c img{ width:30px; height:30px; } .embody_c em{ margin: 0 20px 0 10px; color:#333; font-style: normal; } </style> <script type="text/javascript"> $(function () { try { var lib = eval("("+$("#lib").attr("value")+")"); var html = ""; if (lib.err == 0) { $.each(lib.data, function (i) { var obj = lib.data[i]; //html += '<img src="' + obj.logo + '"/>' + obj.name + " "; html += ' <a href="' + obj.url + '" target="_blank">'; html += ' <img src="' + obj.logo + '">'; html += ' <em><b>' + obj.name + '</b></em>'; html += ' </a>'; }); if (html != "") { setTimeout(function () { $("#lib").html(html); $("#embody").show(); }, 100); } } } catch (err) { } }); </script> <div class="category clearfix"> <div class="category_l"> <img src="http://static.blog.csdn.net/images/category_icon.jpg"> <span>分类:</span> </div> <div class="category_r"> <label onclick="GetCategoryArticles('6078936','hexiechina2010','top','50773942');"> <span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">第三方模块<em>(11)</em></span> <img class="arrow-down" src="http://static.blog.csdn.net/images/arrow_triangle _down.jpg" style="display:inline;"> <img class="arrow-up" src="http://static.blog.csdn.net/images/arrow_triangle_up.jpg" style="display:none;"> <div class="subItem"> <div class="subItem_t"><a href="http://blog.csdn.net/hexiechina2010/article/category/6078936" target="_blank">作者同类文章</a><i class="J_close">X</i></div> <ul class="subItem_l" id="top_6078936"> </ul> </div> </label> </div> </div> <div class="bog_copyright"> <p class="copyright_p">版权声明:本文为博主原创文章,未经博主允许不得转载。</p> </div>
发送方:
/*
* File: main.c
* Author: tianshuai
*
* Created on 2011年11月29日, 下午10:34
*
* 主要实现:发送20个文本消息,然后再发送一个终止消息
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int port=6789;
int main(int argc, char** argv) {
int socket_descriptor; //套接口描述字
int iter=0;
char buf[80];
struct sockaddr_in address;//处理网络通信的地址
bzero(&address,sizeof(address));
address.sin_family=AF_INET;
address.sin_addr.s_addr=inet_addr(”127.0.0.1”);//这里不一样
address.sin_port=htons(port);
//创建一个 UDP socket
socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4 SOCK_DGRAM 数据报套接字(UDP协议)
for(iter=0;iter<=20;iter++)
{
/*
* sprintf(s, ”%8d%8d”, 123, 4567); //产生:” 123 4567”
* 将格式化后到 字符串存放到s当中
*/
sprintf(buf,”data packet with ID %d\n”,iter);
/*int PASCAL FAR sendto( SOCKET s, const char FAR* buf, int len, int flags,const struct sockaddr FAR* to, int tolen);
* s:一个标识套接口的描述字。
* buf:包含待发送数据的缓冲区。
* len:buf缓冲区中数据的长度。
* flags:调用方式标志位。
* to:(可选)指针,指向目的套接口的地址。
* tolen:to所指地址的长度。
*/
sendto(socket_descriptor,buf,sizeof(buf),0,(struct sockaddr *)&address,sizeof(address));
}
sprintf(buf,”stop\n”);
sendto(socket_descriptor,buf,sizeof(buf),0,(struct sockaddr *)&address,sizeof(address));//发送stop 命令
close(socket_descriptor);
printf(”Messages Sent,terminating\n”);
exit(0);
return (EXIT_SUCCESS);
}
接收方:
/*
* File: main.c
* Author: tianshuai
*
* Created on 2011年11月29日, 下午10:34
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int port=6789;
int main(int argc, char** argv) {
int sin_len;
char message[256];
int socket_descriptor;
struct sockaddr_in sin;
printf(”Waiting for data form sender \n”);
bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=htonl(INADDR_ANY);
sin.sin_port=htons(port);
sin_len=sizeof(sin);
socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);
bind(socket_descriptor,(struct sockaddr *)&sin,sizeof(sin));
while(1)
{
recvfrom(socket_descriptor,message,sizeof(message),0,(struct sockaddr *)&sin,&sin_len);
printf(”Response from server:%s\n”,message);
if(strncmp(message,“stop”,4) == 0)//接受到的消息为 “stop”
{
printf(”Sender has told me to end the connection\n”);
break;
&nb
bbc1
sp; }
}
close(socket_descriptor);
exit(0);
return (EXIT_SUCCESS);
}
以上是网上找的。
以下是自己的UDP客户端
int iUDPClientSock = -1;
struct sockaddr_in ServerAddress;
struct sockaddr_in ClientAddress;
/* 设置目的IP地址和端口号 */
ServerAddress.sin_family = AF_INET;
ServerAddress.sin_port = htons(TCP_SERVER_PORT);
u32InetAddr = inet_addr(TCP_SERVER_IP);
ServerAddress.sin_addr.s_addr = u32InetAddr;
memset(&ServerAddress.sin_zero,0,sizeof(ServerAddress.sin_zero));
ClientAddress.sin_family = AF_INET;
ClientAddress.sin_port = htons(2000); //绑定本地的2000端口,可有可无
u32InetAddr = inet_addr(“192.168.0.10”);
ClientAddress.sin_addr.s_addr = u32InetAddr;
memset(&ClientAddress.sin_zero,0,sizeof(ClientAddress.sin_zero));
if ((bind( iUDPClientSock, (struct sockaddr *) &ClientAddress, sizeof(ClientAddress))) < 0) //绑定本地的2000端口,可有可无
{
PlatErrorPrint(0x0000000, “SendTask udp bind err!”);
}
iSendLen = sendto(iUDPClientSock,g_pu8SendDataPos,TCP_SEND_LEN//要发送数据的长度,0,(const struct sockaddr *)&ServerAddress//远方服务器的地址和端口,sizeof(ServerAddress));
if((close(iTCPClientSock)) < 0)//关闭连接
问题调试:
刚开始发送的UDP数据长度TCP_SEND_LEN为15K,现象很奇怪,主站始终接收不到数据,WireShark也监测不到,LWIP的底层接口有时报等待发送完成信号量超时。
后来把发送长度改为1472就可以了。
分析原因:LWIP的配置项中IP层的分片功能没有打开,导致当UDP发送数据太大时,让MAC层发送的数据数大于MTU的1500,会出问题。
而TCP不会出现这个问题,是由于TCP本身有分片功能,不在IP层分片,所以TCP可以发送大于1500的数据。
document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
<div id="digg" articleid="50773942"> <dl id="btnDigg" class="digg digg_disable" onclick="btndigga();"> <dt>顶</dt> <dd>0</dd> </dl> <dl id="btnBury" class="digg digg_disable" onclick="btnburya();"> <dt>踩</dt> <dd>0</dd> </dl> </div> <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank"> </a> </div> <div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank"> </a></div> <script type="text/javascript"> function btndigga() { $(".tracking-ad[data-mod='popu_222'] a").click(); } function btnburya() { $(".tracking-ad[data-mod='popu_223'] a").click(); } </script>
相关文章推荐
- LWIP UDP socket编程 可以指定本地端口号及发送长度不能太长问题分析
- 关于udp socket recvfrom函数的一个易错问题: 如果应用程序指定的接收长度不够怎么办?
- android开发socket编程之udp发送实例分析
- php通过socket编程,以SMTP将邮件发送到指定的QQ邮箱里面。
- Socket编程 关于缓冲区长度问题
- 在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好?
- Windows下Qt应用程序可以连接本地MYSQL不能连接linux的问题
- 解决apache服务器本地可以访问,同局域网内他人不能访问的问题(转)
- 基于udp的网络编程socket的错误10054与SOCKET的发送与接收缓冲区的设置(udp丢包)
- Socket不能选择本地IP连接问题如何解决
- socket编程,server接受到的端口号与client设置的不一致的问题
- Socket编程之UDP发送、接收编程
- 一个关于UDP socket服务端接收长度不正确的问题
- socket 编程UDP通讯问题
- LWIP分析与socket编程方法
- android下socket编程问题:服务器关闭时,客户端发送请求的异常处理
- 网络编程中TCP、UDP的发送缓冲区问题(转)
- linux socket UDP编程发送广播
- 网络编程一:概述、网络模型、TCP\UDP、Socket套接字、UDP发送和接收、UDP聊、阻塞式方法
- 基于UDP协议的网络编程(使用DatagramSocket发送接收数据)