亲爱的 StackOverflowers,
我正在开展一个项目,使用 Microchip 的 TCP/IP 堆栈在我的自定义(和测试)板上的 PIC18F87J60 上实现一些东西。作为测试,我编写了一些代码来设置连接,将其保持 x 秒,然后优雅地关闭它。我已经将它实现为一个有限状态机。我还没有添加发送和接收数据。
但是,我的程序无法建立连接。使用 Wireshark 我注意到我的设备通过 DHCP 成功接收到 IP 地址并且 ARP 解析正确完成。我现在省略了 DNS,因为这也会出错,但我稍后会解决这个问题。 我还看到第一个 SYN 数据包由我的设备发送并由服务器回复,但 3 次握手中的 3e 步骤出错了。确认号只是一个随机数,因此服务器会感到困惑并使用 RST 数据包重置连接。 然后我的设备使用带有另一个随机序列号的 ACK 数据包确认重置,并且服务器以某种方式接受该数据包。然后服务器尝试使用 SYN 数据包再次建立连接,但我的代码不监听传入连接,因此连接结束。
这是我的代码:
#define THIS_IS_STACK_APPLICATION
#include "TCPIP.h"
APP_CONFIG AppConfig;
ROM char serverAddress[] = "data.zienu.eu"; //unused in this codefile: DNS doesn't work yet
ROM char serverIP[] = "80.69.92.56";
short authenticationPort = 5588;
typedef enum _SOCKET_STATE {
SOCKET_DONE = 0,
SETUP_CONNECTION,
CONNECTING,
CONNECTED,
AWAITING_ANSWER,
SENDING_DATA,
CLOSE_CONNECTION,
DISCONNECTING,
DISCONNECTED
} SOCKET_STATE;
typedef struct _CONNECTION {
TCP_SOCKET socketID;
SOCKET_INFO* remoteInfo;
const char* remoteHostName;
WORD remotePort;
SOCKET_STATE state, previousState;
DWORD timeOut;
BYTE purpose;
} CONNECTION;
void InitHardware();
void AuthenticateTask();
void FTPDownloadTask();
void HandleTCPConnection(CONNECTION* connection);
ROM BYTE SerializedMACAddress[6] = {MY_DEFAULT_MAC_BYTE1, MY_DEFAULT_MAC_BYTE2, MY_DEFAULT_MAC_BYTE3, MY_DEFAULT_MAC_BYTE4, MY_DEFAULT_MAC_BYTE5, MY_DEFAULT_MAC_BYTE6};
void InitAppConfig(void) {
AppConfig.Flags.bIsDHCPEnabled = TRUE;
AppConfig.Flags.bInConfigMode = TRUE;
memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul;
AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul;
AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul;
AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul;
AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul;
// Load the default NetBIOS Host Name
memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 10);
FormatNetBIOSName(AppConfig.NetBIOSName);
}
void InitHardware() {
/** \var isBoot (LATH0_bit) tells the boot-interrupt handler that boot is busy */
LATHbits.LATH0 = 1;
ADCON1 |= 0x0f; // adc pins as I/0
CMCON |= 7; // Disable comperator
OSCCON = 0x04;
OSCTUNE = 0x40; //41 MHz
/******************************************************************/
// init========
// Het TRISA en TRISF register moeten goed zijn ingesteld voor de analoge input:
PORTA = 0x00;
TRISA = 0x20; /* Bit 1 and 2 are used by ethernet LEDS */
PORTB = 0x00;
TRISB = 0x00; /* output mode */
PORTC = 0x03; /* LED R en G off */
TRISC = 0xc0; /* Bit 6 and 7 are used by UART 1 */
PORTD = 0x00; /* used to display ethernetsecond_timer in DEBUG mode*/
TRISD = 0x00; /* output mode */
PORTE = 0x00;
TRISE = 0x00; /* output mode */
PORTF = 0x00;
TRISF = 0x0E; /* output mode */
PORTG = 0x00;
TRISG = 0x00;
PORTH = 0x00;
TRISH = 0x00;
/* interrupt priorities are possible with microC */
IPR1bits.ADIP = 0; //give ADC LOW interrupt priority
RCONbits.IPEN = 1; //Enable interrupt priorities
INTCON2bits.RBPU = 1; // Disable internal PORTB pull-ups
INTCONbits.GIEH = 1;
INTCONbits.GIEL = 1;
}
void interrupt low_priority LowISR(void) {
TickUpdate();
}
void interrupt HighISR(void) {
}
void HandleTCPConnection(CONNECTION* connection) {
switch(connection->state) {
case SETUP_CONNECTION:
if(!AppConfig.Flags.bInConfigMode) {
connection->socketID = TCPOpen((DWORD) (PTR_BASE)&serverIP[0], TCP_OPEN_ROM_HOST, connection->remotePort, connection->purpose);
connection->timeOut = TickGet() + TICK_SECOND * 15;
connection->previousState = SETUP_CONNECTION;
connection->state = CONNECTING;
TCPWasReset(connection->socketID);
}
break;
case CONNECTING:
if(TCPIsConnected(connection->socketID)) {
connection->previousState = CONNECTING;
connection->state = CONNECTED;
connection->remoteInfo = TCPGetRemoteInfo(connection->socketID);
connection->timeOut = TickGet() + TICK_SECOND * 10;
}
else if(TickGet() >= connection->timeOut) {
connection->previousState = CONNECTING;
connection->state = CLOSE_CONNECTION;
}
break;
case CONNECTED:
if(TickGet() >= connection->timeOut) {
connection->previousState = CONNECTED;
connection->state = CLOSE_CONNECTION;
}
else if(TCPWasReset(connection->socketID)) {
connection->previousState = CONNECTED;
connection->state = CLOSE_CONNECTION;
}
break;
case CLOSE_CONNECTION:
connection->previousState = CLOSE_CONNECTION;
connection->state = DISCONNECTING;
TCPDisconnect(connection->socketID); //Send a TCP FIN packet
connection->timeOut = TickGet() + TICK_SECOND * 5;
break;
case DISCONNECTING:
if(TCPIsConnected(connection->socketID)) {
connection->previousState = DISCONNECTING;
connection->state = DISCONNECTED;
}
else if(TickGet() >= connection->timeOut) {
TCPDisconnect(connection->socketID);
TCPDisconnect(connection->socketID); //Time out: Send a RST packet and proceed
connection->previousState = DISCONNECTING;
connection->state = DISCONNECTED;
}
break;
case DISCONNECTED:
connection->previousState = DISCONNECTED;
connection->state = SOCKET_DONE;
break;
case SOCKET_DONE:
break;
default:
break;
}
}
void main() {
InitHardware();
TickInit();
InitAppConfig();
StackInit();
CONNECTION connection;
connection.purpose = TCP_PURPOSE_CUSTOM_FTP_CMD;
connection.remoteHostName = serverIP;
connection.remotePort = authenticationPort;
connection.previousState = SOCKET_DONE;
connection.state = SETUP_CONNECTION;
while(TRUE) {
HandleTCPConnection(&connection);
StackTask();
StackApplications();
}
}
这是 Wireshark logs 的屏幕截图.
提前致谢, 比特垃圾
编辑: 这是 wireshark dumpfile .我过滤了 MAC 地址,因此此转储中未显示部分 DHCP 过程。
最佳答案
我解决了这个问题。我认为 TCPIP 堆栈与高科技编译器兼容,但似乎并非如此。 C18 和 XC8 编译器与我发布的代码完美配合。
问候 BitJunky
关于tcp - Microchip TCP/IP 堆栈 PIC18F 无效数据包序列号/确认号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13685790/
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
如果我使用ruby版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更
大家好!我对我的:username字段进行了一个小的验证,它应该是4到30个字符。我写了一个验证::length=>{:within=>4..30,:message=>I18n.t('activerecord.errors.range')-我想显示一个错误各种错误的消息(不像,太长或太短),但这里有一个问题-我可以将最小值和最大值都传递给翻译,以便有类似的东西:用户名应该在4到30个字符之间。目前我有:range:"shouldbebetween%{count}and%{count}characters",这显然不起作用(只是为了检查)。是否可以从范围中获取这些值?谢谢大家的指教!
我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:
我想在Ruby的TCPServer中获取客户端的IP地址。以及(如果可能的话)MAC地址。例如,Ruby中的时间服务器,请参阅评论。tcpserver=TCPServer.new("",80)iftcpserverputs"Listening"loopdosocket=tcpserver.acceptifsocketThread.newdoputs"Connectedfrom"+#HERE!HowcanigettheIPAddressfromtheclient?socket.write(Time.now.to_s)socket.closeendendendend非常感谢!
如果特定语言环境中缺少翻译,如何配置i18n以使用en语言环境翻译?当前已插入翻译缺失消息。我正在使用RoR3.1。 最佳答案 找到相似的question这里是答案:#application.rb#railswillfallbacktoconfig.i18n.default_localetranslationconfig.i18n.fallbacks=true#railswillfallbacktoen,nomatterwhatissetasconfig.i18n.default_localeconfig.i18n.fallback
我正在使用Enumerizegemhttps://github.com/brainspec/enumerize/它允许我以简单的形式使用漂亮的选择。并且此选择中的所有选项均已翻译。en:enumerize:user:sex:male:'Man'female:'Woman'所以,在我的表单中,我选择了变体“男人”和“女人”。当我用“男人”值保存记录时,我得到了“男性”值的性别属性。现在我想在显示页面上将该值显示为“Man”,但是=@user.sex输出为'male'而不是'Man' 最佳答案 我可能会使用.text方法(您可以通过使用
当音乐碰上区块链技术,会擦出怎样的火花?或许周杰伦已经给了我们答案。8月29日下午,B站独家首发周杰伦限定珍藏Demo独家访谈VCR,周杰伦在VCR里分享了《晴天》《青花瓷》《搁浅》《爱在西元前》四首经典歌曲Demo背后的创作故事,并首次公布18年前未发布的神秘作品《纽约地铁》的Demo。在VCR中,方文山和杰威尔音乐提及到“多亏了区块链技术,现在我们可以将这些Demos,变成独一无二具有收藏价值的艺术品,这些Demos可以在薄盒(国内数藏平台)上听到。”如何将音乐与区块链技术相结合,薄盒方面称:“薄盒作为区块链技术服务方,打破传统对于区块链技术只能作为数字收藏的理解。聚焦于区块链技术赋能,在