/* * Read from the TCP port */ static asynStatus readIt(void *drvPvt, asynUser *pasynUser, char *data, size_t maxchars,size_t *nbytesTransfered,int *gotEom) { ttyController_t *tty = (ttyController_t *)drvPvt; int thisRead; int readPollmsec; int reason = 0; epicsTimeStamp startTime; epicsTimeStamp endTime; asynStatus status = asynSuccess; assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s read.\n", tty->IPDeviceName); if (tty->fd == INVALID_SOCKET) { if (tty->flags & FLAG_CONNECT_PER_TRANSACTION) { if ((status = connectIt(drvPvt, pasynUser)) != asynSuccess) return status; } else { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s disconnected:", tty->IPDeviceName); return asynError; } } if (maxchars <= 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s maxchars %d. Why <=0?",tty->IPDeviceName,(int)maxchars); return asynError; } readPollmsec = (int) (pasynUser->timeout * 1000.0); if (readPollmsec == 0) readPollmsec = 1; if (readPollmsec < 0) readPollmsec = -1; #ifdef USE_SOCKTIMEOUT { struct timeval tv; tv.tv_sec = readPollmsec / 1000; tv.tv_usec = (readPollmsec % 1000) * 1000; if (setsockopt(tty->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket receive timeout: %s", tty->IPDeviceName, strerror(SOCKERRNO)); status = asynError; } } #endif if (gotEom) *gotEom = 0; #ifdef USE_POLL { struct pollfd pollfd; pollfd.fd = tty->fd; pollfd.events = POLLIN; epicsTimeGetCurrent(&startTime); while (poll(&pollfd, 1, readPollmsec) < 0) { if (errno != EINTR) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Poll() failed: %s", strerror(errno)); return asynError; } epicsTimeGetCurrent(&endTime); if (epicsTimeDiffInSeconds(&endTime, &startTime)*1000. > readPollmsec) break; } } #endif thisRead = recv(tty->fd, data, (int)maxchars, 0); if (thisRead > 0) { asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead, "%s read %d\n", tty->IPDeviceName, thisRead); tty->nRead += (unsigned long)thisRead; } if (thisRead < 0) { if ((SOCKERRNO != SOCK_EWOULDBLOCK) && (SOCKERRNO != SOCK_EINTR)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s read error: %s", tty->IPDeviceName, strerror(SOCKERRNO)); closeConnection(pasynUser,tty,"Read error"); status = asynError; } else { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s timeout: %s", tty->IPDeviceName, strerror(SOCKERRNO)); status = asynTimeout; } } /* If recv() returns 0 on a SOCK_STREAM (TCP) socket, the connection has closed */ if ((thisRead == 0) && (tty->socketType == SOCK_STREAM)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s connection closed", tty->IPDeviceName); closeConnection(pasynUser,tty,"Read from broken connection"); reason |= ASYN_EOM_END; } if (thisRead < 0) thisRead = 0; *nbytesTransfered = thisRead; /* If there is room add a null byte */ if (thisRead < (int) maxchars) data[thisRead] = 0; else reason |= ASYN_EOM_CNT; if (gotEom) *gotEom = reason; return status; }
void Connection::closeConnectionError(int error) { closeConnection(); m_state = STATE_ERROR; callCallback(error); }
/* * Read from the serial line */ static asynStatus readIt(void *drvPvt, asynUser *pasynUser, char *data, size_t maxchars,size_t *nbytesTransfered,int *gotEom) { ttyController_t *tty = (ttyController_t *)drvPvt; int thisRead; int nRead = 0; int timerStarted = 0; asynStatus status = asynSuccess; assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s read.\n", tty->serialDeviceName); if (tty->fd < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s disconnected:", tty->serialDeviceName); return asynError; } if (maxchars <= 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s maxchars %d Why <=0?\n",tty->serialDeviceName,(int)maxchars); return asynError; } if (tty->readTimeout != pasynUser->timeout) { #ifndef vxWorks /* * Must set flags if we're transitioning * between blocking and non-blocking. */ if ((pasynUser->timeout == 0) || (tty->readTimeout == 0)) { int newFlags = (pasynUser->timeout == 0) ? O_NONBLOCK : 0; if (fcntl(tty->fd, F_SETFL, newFlags) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s file flags: %s", tty->serialDeviceName, strerror(errno)); return asynError; } } /* * Set TERMIOS timeout */ if (pasynUser->timeout > 0) { int t = (pasynUser->timeout * 10) + 1; if (t > 255) t = 255; tty->termios.c_cc[VMIN] = 0; tty->termios.c_cc[VTIME] = t; } else if (pasynUser->timeout == 0) { tty->termios.c_cc[VMIN] = 0; tty->termios.c_cc[VTIME] = 0; } else { tty->termios.c_cc[VMIN] = 1; tty->termios.c_cc[VTIME] = 0; } if (tcsetattr(tty->fd, TCSANOW, &tty->termios) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set \"%s\" c_cc[VTIME]: %s", tty->serialDeviceName, strerror(errno)); return asynError; } #endif tty->readTimeout = pasynUser->timeout; } tty->timeoutFlag = 0; if (gotEom) *gotEom = 0; for (;;) { #ifdef vxWorks /* * vxWorks has neither poll() nor termios but does have the * ability to cancel an operation in progress. If the read * timeout is zero we have to check for characters explicitly * since we don't want to start a timer with 0 delay. */ if (tty->readTimeout == 0) { int nready; ioctl(tty->fd, FIONREAD, (int)&nready); if (nready == 0) { tty->timeoutFlag = 1; break; } } #endif if (!timerStarted && (tty->readTimeout > 0)) { epicsTimerStartDelay(tty->timer, tty->readTimeout); timerStarted = 1; } thisRead = read(tty->fd, data, maxchars); if (thisRead > 0) { asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead, "%s read %d\n", tty->serialDeviceName, thisRead); nRead = thisRead; tty->nRead += thisRead; break; } else { if ((thisRead < 0) && (errno != EWOULDBLOCK) && (errno != EINTR) && (errno != EAGAIN)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s read error: %s", tty->serialDeviceName, strerror(errno)); closeConnection(pasynUser,tty); status = asynError; break; } if (tty->readTimeout == 0) tty->timeoutFlag = 1; } if (tty->timeoutFlag) break; } if (timerStarted) epicsTimerCancel(tty->timer); if (tty->timeoutFlag && (status == asynSuccess)) status = asynTimeout; *nbytesTransfered = nRead; /* If there is room add a null byte */ if (nRead < maxchars) data[nRead] = 0; else if (gotEom) *gotEom = ASYN_EOM_CNT; asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s read %d, return %d\n", tty->serialDeviceName, *nbytesTransfered, status); return status; }
void mainChat(){ string str,temp; int status; status=1; //0 if logout header2(); while(status==1){ cout << endl; kunci.lock(); messageNotifier(); cout << username << "> "; getline(cin >> ws,str); kunci.unlock(); //logout if(str.compare("logout")==0){ status=0; logout(); } //message else if(str.substr(0,8).compare("message ")==0){ temp = str.substr(8); sendMessage(temp); } //create group else if(str.substr(0,7).compare("create ")==0){ temp = str.substr(7); groupCreate(temp); } //join group else if(str.substr(0,5).compare("join ")==0){ temp = str.substr(5); groupJoin(temp); } //leave group else if(str.substr(0,6).compare("leave ")==0){ temp = str.substr(6); groupLeave(temp); } //show chat history else if(str.substr(0,5).compare("show ")==0){ temp = str.substr(5); readChat2(temp); deleteNotifSender(temp); //moveToBottom(..pathnya dimana..); } else if(str.compare("help")==0){ header2(); } //exit else if(str.compare("exit")==0){ status=0; active = false; closeConnection(); exit(0); } //empty input else if(str.compare("")==0){ //do nothing } //wrong input else{ cout <<"Unknown input, please type \'help\' for help." <<endl; } } }
void WebServerInstance::run() { qDebug() << "WebServerInstance::run()"; m_socket = new QTcpSocket(); if (! m_socket->setSocketDescriptor(m_socket_descriptor)) { emit error(m_socket->error()); return; } connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(errorMessage(QAbstractSocket::SocketError))); // connect(this, SIGNAL(readRequestFinished()), // We send response and data automatically. // this, SLOT(sendResponse())); do { m_disconnect_timer->stop(); connect(m_socket, SIGNAL(readyRead()), this, SLOT(readPartialRequest())); handleRequest(); if (! m_request_finished) { closeConnection(); break; } if (m_request.connection() == "close") { closeConnection(); break; } int i; if (m_request.connection() == "keep-alive") { i = m_request.keepAlive(); if (i > 3600) // 1 hour. i = 300; // 5 minutes. } else { i = 300; } // m_disconnect_timer->start(i * 1000); // qDebug() << "waiting for next request on this connection. disconnect in " << i << " seconds."; //m_disconnect_timer->stop(); if (m_request_finished) { disconnect(m_socket, SIGNAL(readyRead()), 0, 0); //emit readRequestFinished(); // Send response. sendResponse(); } if (! m_socket) // to be sure. break; } while (true); qDebug() << "Thread ends here."; if (m_disconnect_timer) { delete m_disconnect_timer; m_disconnect_timer = 0; } }
/* * For server: create the shared memory. Create incoming and * outgoing streams. */ static jint createConnection(SharedMemoryTransport *transport, jlong otherPID, SharedMemoryConnection **connectionPtr) { jint error; char streamPrefix[MAX_IPC_NAME]; SharedMemoryConnection *connection = allocConnection(); if (connection == NULL) { return SYS_NOMEM; } sprintf(connection->name, "%s.%ld", transport->name, otherPID); error = sysSharedMemCreate(connection->name, sizeof(SharedMemory), &connection->sharedMemory, &connection->shared); if (error != SYS_OK) { closeConnection(connection); return error; } memset(connection->shared, 0, sizeof(SharedMemory)); /* This process is the server */ connection->incoming.shared = &connection->shared->toServer; connection->outgoing.shared = &connection->shared->toClient; strcpy(streamPrefix, connection->name); strcat(streamPrefix, ".ctos"); error = createStream(streamPrefix, &connection->incoming); if (error != SYS_OK) { closeConnection(connection); return error; } strcpy(streamPrefix, connection->name); strcat(streamPrefix, ".stoc"); error = createStream(streamPrefix, &connection->outgoing); if (error != SYS_OK) { closeConnection(connection); return error; } error = sysProcessOpen(otherPID, &connection->otherProcess); if (error != SYS_OK) { setLastError(error); closeConnection(connection); return error; } /* * Create an event that signals that the connection is shutting * down. The event is unnamed as it's process local, and is * manually reset (so that a signalling the event will signal * all threads waiting on it). */ error = sysEventCreate(NULL, &connection->shutdown, JNI_TRUE); if (error != SYS_OK) { setLastError(error); closeConnection(connection); return error; } *connectionPtr = connection; return SYS_OK; }
void stateMachine(womim* p_womim) { int id; MUTEX_LOCK(stateMachineMutex); //printf("State = %s, receive message = %s\n", stateToStr(automatonState), msgTypeToStr(p_womim->msg.type)); switch (automatonState) { case OFFLINE_CONNECTION_ATTEMPT: switch (p_womim->msg.type) { case NAK_INSERT: case DISCONNECT_PRED: case DISCONNECT_SUCC: freeWomim(p_womim); nextState(WAIT); break; case INSERT: prec = p_womim->msg.body.insert.sender; sendOther(p_womim->msg.body.insert.sender, true, NAK_INSERT, myAddress); freeWomim(p_womim); break; case ACK_INSERT: prec = p_womim->msg.body.ackInsert.sender; openConnection(prec, true); sendOther(prec, true, NEWSUCC, myAddress); freeWomim(p_womim); nextState(OFFLINE_CONFIRMATION_WAIT); break; default: ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE, __FILE__, __LINE__, "unexpected case : received message %s in state %s", msgTypeToStr(p_womim->msg.type), stateToStr(automatonState)); break; } break; case OFFLINE_CONFIRMATION_WAIT: switch (p_womim->msg.type) { case NEWSUCC: case DISCONNECT_PRED: case DISCONNECT_SUCC: freeWomim(p_womim); nextState(WAIT); break; case INSERT: sendOther(p_womim->msg.body.insert.sender, true, NAK_INSERT, myAddress); freeWomim(p_womim); break; case TRAIN: id = (int) p_womim->msg.body.train.stamp.id; if (addrIsMember(myAddress, p_womim->msg.body.train.circuit)) { p_womim->msg.body.train.stamp.lc++; } releaseWiw(&(lts[id].w.w_w)); lts[id].w.len = 0; if (firstWagon(&(p_womim->msg)) != NULL ) { lts[id].w.w_w.p_wagon = firstWagon(&(p_womim->msg)); lts[id].w.w_w.p_womim = p_womim; lts[id].w.len = (p_womim->msg.len - sizeof(stamp) - sizeof(int) - sizeof(MType) - sizeof(address)); // We do not need to lock the p_womim->pfx.mutex as we are the only thread // accessing to counter p_womim->pfx.counter++; } lts[id].circuit = p_womim->msg.body.train.circuit; lts[id].stamp = p_womim->msg.body.train.stamp; sendTrain(succ, false, lts[id]); if (isInLts(myAddress, lts)) { #ifdef INSERTION_TEST gettimeofday(&trainDate, NULL); timersub(&trainDate, &offlineInitDate, &insertionDuration); floatInsertionDuration = ((double) insertionDuration.tv_sec) * 1000 + ((double) insertionDuration.tv_usec) / 1000; printf("My insertion duration : %.3lfms\n", floatInsertionDuration); printf("number of times automaton has been in state WAIT ; %llu\n", counters.wait_states); #endif /* INSERTION_TEST */ lis = p_womim->msg.body.train.stamp.id; signalArrival(myAddress, lts[lis].circuit); nextState(SEVERAL); int rc = sem_post(sem_init_done); if (rc) ERROR_AT_LINE(EXIT_FAILURE, errno, __FILE__, __LINE__, "error in sem_post"); } freeWomim(p_womim); break; default: ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE, __FILE__, __LINE__, "unexpected case : received message %s in state %s", msgTypeToStr(p_womim->msg.type), stateToStr(automatonState)); freeWomim(p_womim); break; } break; case WAIT: freeWomim(p_womim); break; case ALONE_INSERT_WAIT: switch (p_womim->msg.type) { case DISCONNECT_PRED: case DISCONNECT_SUCC: // May happen in case there are 2 processes on the circuit and one process dies // The other process receives DISCONNECT in SEVERAL state and switched to // ALONE_INSERT_WAIT state, where it receives the DISCONNECT corresponding // to the loss of the second connection freeWomim(p_womim); break; case INSERT: MUTEX_LOCK(mutexWagonToSend); sendOther(p_womim->msg.body.insert.sender, true, ACK_INSERT, myAddress); prec = p_womim->msg.body.insert.sender; freeWomim(p_womim); nextState(ALONE_CONNECTION_WAIT); MUTEX_UNLOCK(mutexWagonToSend); break; default: ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE, __FILE__, __LINE__, "unexpected case : received message %s in state %s", msgTypeToStr(p_womim->msg.type), stateToStr(automatonState)); freeWomim(p_womim); break; } break; case ALONE_CONNECTION_WAIT: switch (p_womim->msg.type) { case DISCONNECT_PRED: nextState(ALONE_INSERT_WAIT); freeWomim(p_womim); break; case INSERT: // In the PhD-thesis algorithm, we are supposed to do a // saveUntilNextstate(p_womim). Sending a NAK_INSERT is more simple. sendOther(p_womim->msg.body.insert.sender, true, NAK_INSERT, myAddress); freeWomim(p_womim); break; case NEWSUCC: succ = p_womim->msg.body.newSucc.sender; int i; for (i = 1; i <= ntr; i++) { int id = ((lis + i) % ntr); (lts[(int) id]).stamp.lc += 1; (lts[(int) id]).circuit = myAddress | prec; (lts[(int) id]).w.w_w.p_wagon = NULL; (lts[(int) id]).w.w_w.p_womim = NULL; (lts[(int) id]).w.len = 0; sendTrain(succ, false, lts[(int) id]); } freeWomim(p_womim); nextState(SEVERAL); break; default: ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE, __FILE__, __LINE__, "unexpected case : received message %s in state %s", msgTypeToStr(p_womim->msg.type), stateToStr(automatonState)); freeWomim(p_womim); break; } break; case SEVERAL: switch (p_womim->msg.type) { case TRAIN: if (addrIsMember(myAddress, p_womim->msg.body.train.circuit)) { if (isRecentTrain(p_womim->msg.body.train.stamp, lts, lis)) { #ifdef INSERTION_TEST if (theLostPrec != 0) { if (recentlyLostMyPred) { gettimeofday(&firstRecentTrainDate, NULL); recentlyLostMyPred = false; } if (!isInLts(theLostPrec,lts)) { gettimeofday(&firstNewCircuitDate, NULL); theLostPrec = 0; timersub(&firstRecentTrainDate, &discoPredDate, &recoveryRecentTrainDuration); timersub(&firstNewCircuitDate, &discoPredDate, &recoveryNewCircuitDuration); floatRecoveryRecentTrainDuration = ((double) recoveryRecentTrainDuration.tv_sec) * 1000 + ((double) recoveryRecentTrainDuration.tv_usec) / 1000; floatRecoveryNewCircuitDuration = ((double) recoveryNewCircuitDuration.tv_sec) * 1000 + ((double) recoveryNewCircuitDuration.tv_usec) / 1000; printf("Disconnection pred recovery :\n"); printf("\t- First recent train after %.3lfms\n", floatRecoveryRecentTrainDuration); printf("\t- Up-to-date circuit received after %.3lfms\n", floatRecoveryNewCircuitDuration); } } #endif /* INSERTION_TEST */ trainHandling(p_womim); lis = p_womim->msg.body.train.stamp.id; if (succ != 0) sendTrain(succ, false, lts[lis]); } } else { ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE, __FILE__, __LINE__, "myAddress not in the circuit ==> Suicide"); } freeWomim(p_womim); break; case INSERT: closeConnection(prec, true); sendOther(p_womim->msg.body.insert.sender, true, ACK_INSERT, prec); prec = p_womim->msg.body.insert.sender; addrAppendArrived(&cameProc, prec); freeWomim(p_womim); break; case NEWSUCC: if (succ != 0) closeConnection(succ, false); succ = p_womim->msg.body.newSucc.sender; int i; for (i = 1; i <= ntr; i++) { sendTrain(succ, false, lts[(lis + i) % ntr]); } freeWomim(p_womim); break; case DISCONNECT_PRED: #ifdef INSERTION_TEST gettimeofday(&discoPredDate, NULL); recentlyLostMyPred = true; theLostPrec = prec; #endif /* INSERTION_TEST */ MUTEX_LOCK(mutexWagonToSend); while (!(addrIsEqual(prec,myAddress))) { if (openConnection(prec, true) != (-1)) { sendOther(prec, true, NEWSUCC, myAddress); freeWomim(p_womim); nextState(SEVERAL); MUTEX_UNLOCK(stateMachineMutex); MUTEX_UNLOCK(mutexWagonToSend); return; } addrAppendGone(&cameProc, &goneProc, prec); prec = addrPrec(prec, lts[lis].circuit); } signalDepartures(goneProc, lts[lis].circuit, true); goneProc = 0; int aRound; for (aRound = 1; aRound <= NR; aRound++) { int i; for (i = 1; i <= ntr; i++) { int id = (lis + i) % ntr; int round = (lts[id].stamp.round + aRound) % NR; bqueueExtend(wagonsToDeliver, unstableWagons[id][round]); cleanList(unstableWagons[id][round]); } } bqueueEnqueue(wagonsToDeliver, wagonToSend); wagonToSend = newWiw(); freeWomim(p_womim); #ifdef INSERTION_TEST gettimeofday(&firstNewCircuitDate, NULL); timersub(&firstNewCircuitDate, &discoPredDate, &recoveryNewCircuitDuration); floatRecoveryNewCircuitDuration = ((double) recoveryNewCircuitDuration.tv_sec) * 1000 + ((double) recoveryNewCircuitDuration.tv_usec) / 1000; printf("I am alone !\n" "%.3lfms since the DISCONNECT_PRED message\n", floatRecoveryNewCircuitDuration); #endif /* INSERTION_TEST */ nextState(ALONE_INSERT_WAIT); MUTEX_UNLOCK(stateMachineMutex); MUTEX_UNLOCK(mutexWagonToSend); pthread_cond_signal(&condWagonToSend); break; case DISCONNECT_SUCC: succ = 0; freeWomim(p_womim); break; default: ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE, __FILE__, __LINE__, "unexpected case : received message %s in state %s", msgTypeToStr(p_womim->msg.type), stateToStr(automatonState)); break; } break; default: ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE, __FILE__, __LINE__, "Unknown state : %d", automatonState); freeWomim(p_womim); break; } MUTEX_UNLOCK(stateMachineMutex); }
boolean NanoESP::endUdpServer(int id) { return closeConnection(id); }
ConnectionModbusPoint::~ConnectionModbusPoint() { closeConnection(); }
WdtSocket::~WdtSocket() { closeConnection(); }
static apr_status_t sendRecvBuffer(apr_time_t *t, const char *buf, apr_size_t size, apr_pool_t *pool) { apr_socket_t *sock; apr_status_t rv; apr_size_t len = size, thistime = size; char *recvBuf; apr_time_t testStart = apr_time_now(), testEnd; int i; if (! sockAddr) { rv = apr_sockaddr_info_get(&sockAddr, "127.0.0.1", APR_UNSPEC, testPort, 0, pool); if (rv != APR_SUCCESS) { reportError("Unable to get socket info", rv, pool); return rv; } /* make sure we can connect to daemon before we try tests */ rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, APR_PROTO_TCP, pool); if (rv != APR_SUCCESS) { reportError("Unable to create IPv4 stream socket", rv, pool); return rv; } rv = apr_socket_connect(sock, sockAddr); if (rv != APR_SUCCESS) { reportError("Unable to connect to echod!", rv, pool); apr_socket_close(sock); return rv; } apr_socket_close(sock); } recvBuf = apr_palloc(pool, size); if (! recvBuf) { reportError("Unable to allocate buffer", ENOMEM, pool); return ENOMEM; } *t = 0; /* START! */ testStart = apr_time_now(); rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, APR_PROTO_TCP, pool); if (rv != APR_SUCCESS) { reportError("Unable to create IPv4 stream socket", rv, pool); return rv; } rv = apr_socket_connect(sock, sockAddr); if (rv != APR_SUCCESS) { reportError("Unable to connect to echod!", rv, pool); apr_socket_close(sock); return rv; } for (i = 0; i < 3; i++) { len = size; thistime = size; rv = apr_socket_send(sock, buf, &len); if (rv != APR_SUCCESS || len != size) { reportError(apr_psprintf(pool, "Unable to send data correctly (iteration %d of 3)", i) , rv, pool); closeConnection(sock); apr_socket_close(sock); return rv; } do { len = thistime; rv = apr_socket_recv(sock, &recvBuf[size - thistime], &len); if (rv != APR_SUCCESS) { reportError("Error receiving from socket", rv, pool); break; } thistime -= len; } while (thistime); } closeConnection(sock); apr_socket_close(sock); testEnd = apr_time_now(); /* STOP! */ if (thistime) { reportError("Received less than we sent :-(", rv, pool); return rv; } if (strncmp(recvBuf, buf, size) != 0) { reportError("Received corrupt data :-(", 0, pool); printf("We sent:\n%s\nWe received:\n%s\n", buf, recvBuf); return EINVAL; } *t = testEnd - testStart; return APR_SUCCESS; }
void Connection::parsePacket(const boost::system::error_code& error) { m_connectionLock.lock(); m_readTimer.cancel(); if (error) { handleReadError(error); } if (m_connectionState != CONNECTION_STATE_OPEN || m_readError) { closeConnection(); m_connectionLock.unlock(); return; } uint32_t timePassed = std::max<uint32_t>(1, (time(nullptr) - m_timeConnected) + 1); if ((++m_packetsSent / timePassed) > (uint32_t)g_config.getNumber(ConfigManager::MAX_PACKETS_PER_SECOND)) { std::cout << convertIPToString(getIP()) << " disconnected for exceeding packet per second limit." << std::endl; closeConnection(); m_connectionLock.unlock(); return; } if (timePassed > 2) { m_timeConnected = time(nullptr); m_packetsSent = 0; } //Check packet checksum uint32_t checksum; int32_t len = m_msg.getMessageLength() - m_msg.getReadPos() - 4; if (len > 0) { checksum = adlerChecksum(m_msg.getBuffer() + m_msg.getReadPos() + 4, len); } else { checksum = 0; } uint32_t recvChecksum = m_msg.get<uint32_t>(); if (recvChecksum != checksum) { // it might not have been the checksum, step back m_msg.SkipBytes(-4); } if (!m_receivedFirst) { // First message received m_receivedFirst = true; if (!m_protocol) { // Game protocol has already been created at this point m_protocol = m_service_port->make_protocol(recvChecksum == checksum, m_msg); if (!m_protocol) { closeConnection(); m_connectionLock.unlock(); return; } m_protocol->setConnection(shared_from_this()); } else { m_msg.GetByte(); // Skip protocol ID } m_protocol->onRecvFirstMessage(m_msg); } else { m_protocol->onRecvMessage(m_msg); // Send the packet to the current protocol } try { m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout)); m_readTimer.async_wait( std::bind(&Connection::handleReadTimeout, std::weak_ptr<Connection>(shared_from_this()), std::placeholders::_1)); // Wait to the next packet boost::asio::async_read(getHandle(), boost::asio::buffer(m_msg.getBuffer(), NetworkMessage::header_length), std::bind(&Connection::parseHeader, shared_from_this(), std::placeholders::_1)); } catch (boost::system::system_error& e) { if (m_logError) { std::cout << "[Network error - Connection::parsePacket] " << e.what() << std::endl; m_logError = false; } closeConnection(); } m_connectionLock.unlock(); }
void GlobalScoresWindow::connectionError() { // Displays an error message regarding the connection and closes it qDebug() << tcpSocket.errorString(); closeConnection(); }
/* Read client message */ void readCallback(struct ev_loop *loop, struct ev_io *watcher, int revents) { if (EV_ERROR & revents) { puts ("got invalid event"); return; } struct clientStatus *thisClient = (clientStatus*)watcher; // Receive message from client socket byte buffer[BUFFER_SIZE]; size_t read; read = recv(watcher->fd, buffer, BUFFER_SIZE, 0); if (read < 0) { puts ("read error"); // TODO shut down this connection return; } if (read == 0) { // Stop and free watcher if client socket is closing closeConnection(watcher); // TODO is the socket close in this function necessary since the other side closed it anyway? puts("peer closing"); return; } // Go through the bytes read for (int i=0; i<read; i++) { // Are we reading (and ignoring) the rest of the headers? if (thisClient->readStatus == 500) { // looking for the second \n to signify the end of headers if (buffer[i]=='\n') { thisClient->readStatus = 1000; // Now we are ready to respond receivedHeaders(thisClient); // Now we can respond return; // No point processing the rest of the stuff from the client: TODO what about skipping everything after the first line? } else { // TODO throw error and give up - '\r' not followed by '\n' } } if (thisClient->readStatus == 400) { // looking for the second \r to signify the end of headers, or the next header if (buffer[i]=='\r') { thisClient->readStatus = 500; // Waiting for the next '\n' } else { thisClient->readStatus = 200; // Back to reading another header line } } if (thisClient->readStatus == 300) { // looking for the first \n if (buffer[i]=='\n') { thisClient->readStatus = 400; // Waiting for the next '\r' } else { // TODO throw error and give up - '\r' not followed by '\n' } } if (thisClient->readStatus == 200) { // reading (and ignoring) the rest of the headers if (buffer[i]=='\r') { thisClient->readStatus = 300; // Waiting for a '\n' } } // Are we reading the first line of the header? // Did we just receive the '\r' and are we now waiting for the '\n' ? if (thisClient->readStatus == 100) { if (buffer[i]=='\n') { thisClient->readStatus = 200; // Great, now we're going thru the rest of the headers } else { // Bugger, it wasn't a \n. Drop the connection // TODO shut down the connection } } // Reading the rest of the first header line, waiting for the '\r' if (thisClient->readStatus == 20) { if (buffer[i]=='\r') { thisClient->readStatus = 100; // Now waiting for the '\n' } } // Reading the '.js' after the client id if (thisClient->readStatus == 12) { if (buffer[i]=='s') { thisClient->readStatus=20; } else { // drop the connection, they might be trying to access the favicon or something annoying like that puts ("Not a .js request!"); closeConnection(watcher); return; } } if (thisClient->readStatus == 11) { if (buffer[i]=='j') { thisClient->readStatus=12; } else { // drop the connection, they might be trying to access the favicon or something annoying like that puts ("Not a .js request!"); closeConnection(watcher); return; } } // Reading the client id up to the '.js' if (thisClient->readStatus == 10) { if (buffer[i]=='.') { thisClient->clientId[thisClient->clientIdLen]=0; // Put the null terminator on the end of the client id thisClient->readStatus = 11; // now reading the rest of the first header line, waiting for the '\r' } else { // Record the client id if (thisClient->clientIdLen < MAX_CLIENT_ID_LEN) { thisClient->clientId[thisClient->clientIdLen] = buffer[i]; thisClient->clientIdLen++; } else { // Client id too long // TODO shut down the connection and print a warning } } } // Are we receiving the first line's "GET /" part? if (thisClient->readStatus == 0) { if (buffer[i]=='/') { thisClient->readStatus = 10; // Reading the client id now thisClient->clientIdLen = 0; } } } }
void TripPlanner::connectionClosedByServer() { if (nextBlockSize != 0xFFFF) statusLabel->setText(tr("Error: Connection closed by server")); closeConnection(); }
Client::~Client() { closeConnection(); }
void TripPlanner::error() { statusLabel->setText(tcpSocket.errorString()); closeConnection(); }
//------------------------------------------------------------------------------ // closeConnection() -- request that the connection is closed (shutdown) //------------------------------------------------------------------------------ bool TcpHandler::closeConnection() { bool success = true; #if defined(WIN32) if (::closesocket(socketNum) == SOCKET_ERROR) { #else if (::shutdown(socketNum, SHUT_RDWR) == SOCKET_ERROR) { #endif std::perror("TcpHandler::closeConnection(): error! \n"); success = false; } connected = false; connectionTerminated = true; return BaseClass::closeConnection() && success; } // ------------------------------------------------------------- // sendData() -- Send data to our connected TCP socket // ------------------------------------------------------------- bool TcpHandler::sendData(const char* const packet, const int size) { if (!isConnected() || hasBeenTerminated()) return false; if (socketNum == INVALID_SOCKET) return false; int result = ::send(socketNum, packet, size, 0); if (result == SOCKET_ERROR) { connected = false; connectionTerminated = true; #if defined(WIN32) int err = WSAGetLastError(); if (isMessageEnabled(MSG_ERROR)) { std::cerr << "TcpHandler::sendData(): sendto error: " << err << " hex=0x" << std::hex << err << std::dec << std::endl; } #else std::perror("TcpHandler::sendData(): sendto error msg"); if (isMessageEnabled(MSG_ERROR)) { std::cerr << "TcpHandler::sendData(): sendto error result: " << result << std::endl; } #endif return false; } return true; } // ------------------------------------------------------------- // recvData() -- Receive data from our connected TCP socket // ------------------------------------------------------------- unsigned int TcpHandler::recvData(char* const packet, const int maxSize) { if (!isConnected() || hasBeenTerminated()) return 0; if (socketNum == INVALID_SOCKET) return 0; unsigned int n = 0; // default return value (no data) // Try to receive the data int result = ::recv(socketNum, packet, maxSize, 0); // Did we received any data? if (result > 0) { // We've received data -- all is well. n = static_cast<unsigned int>(result); } // Did we receive a zero? else if (result == 0) { // Received a zero -- connection closed by other side closeConnection(); } // Do we have an error code? else if (result < 0) { // For error conditions, check for non-blocking and adjust result // to indicate there is no error if (errno != EAGAIN && errno != EWOULDBLOCK) { // Error condition! Close the conntection std::perror("TcpHandler::recvData(): "); closeConnection(); } } return n; } } // End Basic namespace
void shmemBase_closeConnection(SharedMemoryConnection *connection) { clearLastError(); closeConnection(connection); }
/* We need to write a tygem parser that doesn't need to be different for tom FIXME */ void TomConnection::handleServerInfo(unsigned char * msg, unsigned int length) { char * p = (char *)msg; int i, j; ServerItem * si; #ifdef RE_DEBUG for(i = 0; i < length; i++) printf("%c", p[i]); printf("\n"); #endif //RE_DEBUG while(p < ((char *)msg + length)) { while(p < ((char *)msg + length - 1) && p[0] != '\n') p++; p++; //FIXME, check for size if(strncmp(p, "/LIVE ", 6) == 0) { //same as for /SERVER but with only 2 [], name and ip } else if(strncmp(p, "/LECTURE ", 9) == 0) { //same as for /SERVER but with only 2 [], name and ip } else if(strncmp(p, "/SERVER ", 8) == 0 || strncmp(p, "/_SERVER ", 9) == 0) //whats the "_" FIXME { //TOM has only 2 [], name and ip if(p[1] == '_') p++; p += 8; unsigned char ipaddr[16]; unsigned char name[20]; i = 0; while(i < 2 && p < ((char *)msg + length)) { if(*p != '[') { qDebug("Server info parse error"); closeConnection(); return; } p++; si = new ServerItem(); unsigned char * dest; if(i == 1) dest = ipaddr; else if(i == 0) dest = name; j = 0; while(*p != ']' && p < ((char *)msg + length)) { if((i == 1 && j < 15) || (i == 0 && j < 19)) dest[j++] = *p; p++; } if(i == 0 || i == 1) { dest[j++] = 0x00; } p += 2; if(i == 1) { strncpy(si->ipaddress, (const char *)ipaddr, 16); si->name = serverCodec->toUnicode((char *)name, strlen((char *)name)); qDebug("Server: %s", ipaddr); serverList.push_back(si); } i++; if(i == 7) p--; //no space } } else if(strncmp(p, "/ENCRYPT ", 9) == 0) { //FIXME //[encode] [on] } } /* We close here because this first time, its going to close * anyway, and if we don't close here, we'll get an error * and lose the object */ setState(RECONNECTING); closeConnection(false); if(reconnectToServer() < 0) { qDebug("User canceled"); closeConnection(false); setState(CANCELED); //if(dispatch) // dispatch->onError(); //not great... FIXME return; } //sendLogin(); }
terrama2::core::ProcessLogger::~ProcessLogger() { closeConnection(); }
/* * Processes events about the state of an RsslReactorChannel. */ RsslReactorCallbackRet channelEventCallback(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslReactorChannelEvent *pConnEvent) { ChannelStorage *pCommand = (ChannelStorage*)pReactorChannel->userSpecPtr; switch(pConnEvent->channelEventType) { case RSSL_RC_CET_CHANNEL_UP: { /* A channel that we have requested via rsslReactorConnect() has come up. Set our * file descriptor sets so we can be notified to start calling rsslReactorDispatch() for * this channel. This will drive the process of setting up the connection * by exchanging the Login, Directory, and (if not already loaded)Dictionary messages. * The application will receive the response messages in the appropriate callback * function we specified. */ #ifdef _WIN32 int rcvBfrSize = 65535; int sendBfrSize = 65535; RsslErrorInfo rsslErrorInfo; #endif printf("Connection up! Channel fd=%d\n\n", pReactorChannel->socketId); /* Set file descriptor. */ FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); /* Save the channel on our info structure. */ pCommand->reactorChannel = pReactorChannel; #ifdef _WIN32 /* WINDOWS: change size of send/receive buffer since it's small by default */ if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } #endif if (xmlTrace) { RsslTraceOptions traceOptions; RsslErrorInfo rsslErrorInfo; rsslClearTraceOptions(&traceOptions); traceOptions.traceMsgFileName = traceOutputFile; traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_TO_STDOUT | RSSL_TRACE_TO_MULTIPLE_FILES | RSSL_TRACE_WRITE | RSSL_TRACE_READ; traceOptions.traceMsgMaxFileSize = 100000000; rsslReactorChannelIoctl(pReactorChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &rsslErrorInfo); } return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_READY: { pCommand->reactorChannelReady = RSSL_TRUE; return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_FD_CHANGE: { /* The file descriptor representing the RsslReactorChannel has been changed. * Update our file descriptor sets. */ printf("Fd change: %d to %d\n", pReactorChannel->oldSocketId, pReactorChannel->socketId); FD_CLR(pReactorChannel->oldSocketId, &readFds); FD_CLR(pReactorChannel->oldSocketId, &exceptFds); FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_DOWN: { /* The channel has failed and has gone down. Print the error, close the channel, and reconnect later. */ printf("Connection down: Channel fd=%d.\n", pReactorChannel->socketId); if (pConnEvent->pError) printf(" Error text: %s\n\n", pConnEvent->pError->rsslError.text); /* It is important to make sure that no more interface calls are made using the channel after * calling rsslReactorCloseChannel(). Because this application is single-threaded, it is safe * to call it inside callback functions. */ closeConnection(pReactor, pReactorChannel, pCommand); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_DOWN_RECONNECTING: { printf("Connection down, reconnecting. Channel fd=%d\n", pReactorChannel->socketId); if (pReactorChannel->socketId != REACTOR_INVALID_SOCKET) { FD_CLR(pReactorChannel->socketId, &readFds); FD_CLR(pReactorChannel->socketId, &exceptFds); } clearChannelStorage(pCommand); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_WARNING: { /* We have received a warning event for this channel. Print the information and continue. */ printf("Received warning for Channel fd=%d.\n", pReactorChannel->socketId); printf(" Error text: %s\n\n", pConnEvent->pError->rsslError.text); return RSSL_RC_CRET_SUCCESS; } default: { printf("Unknown connection event!\n"); cleanUpAndExit(-1); } } return RSSL_RC_CRET_SUCCESS; }
static void spk_destruct (volatile SpeechSynthesizer *spk) { closeConnection(); clearSettings(); }
int aConn::Post2KVdataTSQ(void *ptr) { int KVdatathrindex; int bucket; aMsg *aM = (aMsg *) ptr; aMsg *aM1; //DBUG(ALOG_TCONN, "CONN(%p)BUSY val:%d BEFORE QUEING MSG(%p)",this,__sync_val_compare_and_swap(&(this->Busy), 9999,9999),aM); if (__sync_bool_compare_and_swap(&(this->Busy), 0, 1)) { DBUG(ALOG_TCONN, "CONN(%p)Post2KVDATA:BUSY SET TO 1 val:%d ptr(%p) ", this, __sync_val_compare_and_swap(&(this->Busy), 99,99), &(this->Busy)); // check if pending messages on aC aM1 = (aMsg *) this->PendingCmdQ->aSQget(); if (aM1) { DBUG(ALOG_TCONN, "CONN(%p)got PendingCmdQ msg(%p)", this, aM1); if (ptr) { this->PendingCmdQ->aSQput(aM); } aM = aM1; } if (aM) { if (aM->aC->cmd.ctype == ACACHED_CMD_GETS) { this->Post2KVdataGets(aM); } else if (aM->aC->cmd.ctype == ACACHED_CMD_QUIT) { closeConnection(aM->aC->cSockFd, aM->aC->commRead_wptr); if (!__sync_bool_compare_and_swap(&(this->Busy), 1, 0)) { ALERT( ALOG_ALERT, "CONN(%p)CMD:QUIT NOT ABLE TO SWAP CONN BUSY val:%d", this, __sync_val_compare_and_swap(&(this->Busy), 99, 99)); } SGAptr->aMsgRelease(aM); } else { // cmd will be SET bucket = aM->HdrIN.aMsgHdrIN.hashval & SGAptr->hashmask; if (bucket <= SGAptr->hashsize / SGAptr->numCores) { KVdatathrindex = 0; } else { KVdatathrindex = 1; } DBUG(ALOG_ALERT, "KV index:%d", KVdatathrindex); //printf("posting to kvdata val:%d\n",__sync_val_compare_and_swap(&(this->Busy), 99,99) ); SGAptr->aTSQGKVdata[KVdatathrindex]->aTSQputMsg(aM); } } else { if (!__sync_bool_compare_and_swap(&(this->Busy), 1, 0)) { ALERT( ALOG_ALERT, "CONN(%p)NOT ABLE TO SWAP CONN BUSY val:%d", this, __sync_val_compare_and_swap(&(this->Busy), 99, 99)); } } } else { DBUG(ALOG_TCONN, "CONN(%p)BUSY val:%d QUEING MSG(%p)CMD:%d", this, __sync_val_compare_and_swap(&(this->Busy), 99,99), aM, aM->aC->cmd.ctype); //queue to connection list this->PendingCmdQ->aSQput(aM); DBUG(ALOG_TCONN, "CONN(%p)BUSY val:%d AFTER QUEING MSG(%p)", this, __sync_val_compare_and_swap(&(this->Busy), 99,99), aM); } return 0; }
Connection::~Connection() { closeConnection(); delete m_protocol; delete m_crypto; }
Ati::~Ati(void) { // close the connection closeConnection(); }
/* * Write to the serial line */ static asynStatus writeIt(void *drvPvt, asynUser *pasynUser, const char *data, size_t numchars,size_t *nbytesTransfered) { ttyController_t *tty = (ttyController_t *)drvPvt; int thisWrite; int nleft = numchars; int timerStarted = 0; asynStatus status = asynSuccess; assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s write.\n", tty->serialDeviceName); asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars, "%s write %d\n", tty->serialDeviceName, numchars); if (tty->fd < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s disconnected:", tty->serialDeviceName); return asynError; } if (numchars == 0) { *nbytesTransfered = 0; return asynSuccess; } if (tty->writeTimeout != pasynUser->timeout) { #ifndef vxWorks /* * Must set flags if we're transitioning * between blocking and non-blocking. */ if ((pasynUser->timeout == 0) || (tty->writeTimeout == 0)) { int newFlags = (pasynUser->timeout == 0) ? O_NONBLOCK : 0; if (fcntl(tty->fd, F_SETFL, newFlags) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s file flags: %s", tty->serialDeviceName, strerror(errno)); return asynError; } } #endif tty->writeTimeout = pasynUser->timeout; } tty->timeoutFlag = 0; nleft = numchars; #ifdef vxWorks if (tty->writeTimeout >= 0) #else if (tty->writeTimeout > 0) #endif { epicsTimerStartDelay(tty->timer, tty->writeTimeout); timerStarted = 1; } for (;;) { thisWrite = write(tty->fd, (char *)data, nleft); if (thisWrite > 0) { tty->nWritten += thisWrite; nleft -= thisWrite; if (nleft == 0) break; data += thisWrite; } if (tty->timeoutFlag || (tty->writeTimeout == 0)) { status = asynTimeout; break; } if ((thisWrite < 0) && (errno != EWOULDBLOCK) && (errno != EINTR) && (errno != EAGAIN)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s write error: %s", tty->serialDeviceName, strerror(errno)); closeConnection(pasynUser,tty); status = asynError; break; } } if (timerStarted) epicsTimerCancel(tty->timer); *nbytesTransfered = numchars - nleft; asynPrint(pasynUser, ASYN_TRACE_FLOW, "wrote %lu to %s, return %s\n", (unsigned long)*nbytesTransfered, tty->serialDeviceName, pasynManager->strStatus(status)); return status; }
void TripPlanner::stopSearch() { statusLabel->setText(tr("Search stopped")); closeConnection(); }
ConnPostgres::~ConnPostgres() { closeConnection(); }
/* * Write to the TCP port */ static asynStatus writeIt(void *drvPvt, asynUser *pasynUser, const char *data, size_t numchars,size_t *nbytesTransfered) { ttyController_t *tty = (ttyController_t *)drvPvt; int thisWrite; asynStatus status = asynSuccess; int writePollmsec; int epicsTimeStatus; epicsTimeStamp startTime; epicsTimeStamp endTime; int haveStartTime; assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s write.\n", tty->IPDeviceName); asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars, "%s write %lu\n", tty->IPDeviceName, (unsigned long)numchars); *nbytesTransfered = 0; if (tty->fd == INVALID_SOCKET) { if (tty->flags & FLAG_CONNECT_PER_TRANSACTION) { if ((status = connectIt(drvPvt, pasynUser)) != asynSuccess) return status; } else { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s disconnected:", tty->IPDeviceName); return asynError; } } if (numchars == 0) return asynSuccess; writePollmsec = (int) (pasynUser->timeout * 1000.0); if (writePollmsec == 0) writePollmsec = 1; if (writePollmsec < 0) writePollmsec = -1; #ifdef USE_SOCKTIMEOUT { struct timeval tv; tv.tv_sec = writePollmsec / 1000; tv.tv_usec = (writePollmsec % 1000) * 1000; if (setsockopt(tty->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket send timeout: %s", tty->IPDeviceName, strerror(SOCKERRNO)); return asynError; } } #endif haveStartTime = 0; for (;;) { #ifdef USE_POLL struct pollfd pollfd; pollfd.fd = tty->fd; pollfd.events = POLLOUT; epicsTimeGetCurrent(&startTime); while (poll(&pollfd, 1, writePollmsec) < 0) { if (errno != EINTR) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Poll() failed: %s", strerror(errno)); return asynError; } epicsTimeGetCurrent(&endTime); if (epicsTimeDiffInSeconds(&endTime, &startTime)*1000 > writePollmsec) break; } #endif for (;;) { thisWrite = send(tty->fd, (char *)data, (int)numchars, 0); if (thisWrite >= 0) break; if (SOCKERRNO == SOCK_EWOULDBLOCK || SOCKERRNO == SOCK_EINTR) { if (!haveStartTime) { epicsTimeStatus = epicsTimeGetCurrent(&startTime); assert(epicsTimeStatus == epicsTimeOK); haveStartTime = 1; } else if (pasynUser->timeout >= 0) { epicsTimeStatus = epicsTimeGetCurrent(&endTime); assert(epicsTimeStatus == epicsTimeOK); if (epicsTimeDiffInSeconds(&endTime, &startTime) > pasynUser->timeout) { thisWrite = 0; break; } } epicsThreadSleep(SEND_RETRY_DELAY); } else break; } if (thisWrite > 0) { tty->nWritten += (unsigned long)thisWrite; *nbytesTransfered += thisWrite; numchars -= thisWrite; if (numchars == 0) break; data += thisWrite; } else if (thisWrite == 0) { status = asynTimeout; break; } else { epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s write error: %s", tty->IPDeviceName, strerror(SOCKERRNO)); closeConnection(pasynUser,tty,"Write error"); status = asynError; break; } } asynPrint(pasynUser, ASYN_TRACE_FLOW, "wrote %lu to %s, return %s.\n", (unsigned long)*nbytesTransfered, tty->IPDeviceName, pasynManager->strStatus(status)); return status; }