wait some time for initial garbage in tcp mode and fixed dumping garbage, use FIONREAD instead of MSG_PEEK for cygwin (fixes #132)

This commit is contained in:
john30
2017-11-19 11:58:31 +01:00
parent 0c16712c5f
commit b18d7f38bb
Regular → Executable
+14 -8
View File
@@ -41,6 +41,8 @@
namespace ebusd { namespace ebusd {
#define MTU 1540
Device::~Device() { Device::~Device() {
close(); close();
} }
@@ -205,7 +207,7 @@ result_t SerialDevice::open() {
tcgetattr(m_fd, &m_oldSettings); tcgetattr(m_fd, &m_oldSettings);
// create new settings // create new settings
memset(&newSettings, '\0', sizeof(newSettings)); memset(&newSettings, 0, sizeof(newSettings));
newSettings.c_cflag |= (B2400 | CS8 | CLOCAL | CREAD); newSettings.c_cflag |= (B2400 | CS8 | CLOCAL | CREAD);
newSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // non-canonical mode newSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // non-canonical mode
@@ -269,18 +271,23 @@ result_t NetworkDevice::open() {
value = 1; value = 1;
setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<void*>(&value), sizeof(value)); setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<void*>(&value), sizeof(value));
} }
if (ret == 0) { if (ret >= 0) {
ret = connect(m_fd, (struct sockaddr*)&m_address, sizeof(m_address)); ret = connect(m_fd, (struct sockaddr*)&m_address, sizeof(m_address));
} }
if (ret < 0) { if (ret < 0) {
close(); close();
return RESULT_ERR_GENERIC_IO; return RESULT_ERR_GENERIC_IO;
} }
if (!m_udp) {
usleep(25000); // wait 25ms for potential initial garbage
}
int cnt; int cnt;
if (ioctl(m_fd, FIONREAD, &cnt) >= 0 && cnt > 1) { symbol_t buf[MTU];
while (ioctl(m_fd, FIONREAD, &cnt) >= 0 && cnt > 1) {
// skip buffered input // skip buffered input
symbol_t buf[256]; ssize_t read = ::read(m_fd, &buf, MTU);
while (::read(m_fd, &buf, 256) > 0) { if (read <= 0) {
break;
} }
} }
if (m_bufSize == 0) { if (m_bufSize == 0) {
@@ -298,9 +305,8 @@ result_t NetworkDevice::open() {
} }
void NetworkDevice::checkDevice() { void NetworkDevice::checkDevice() {
symbol_t value; int cnt;
ssize_t c = ::recv(m_fd, &value, 1, MSG_PEEK | MSG_DONTWAIT); if (ioctl(m_fd, FIONREAD, &cnt) < 0) {
if (c == 0 || (c < 0 && errno != EAGAIN)) {
m_bufLen = 0; // flush read buffer m_bufLen = 0; // flush read buffer
close(); close();
} }