void TCPBase::NewConnection() { if(IPCSocket) { // connection should be already finished return; } disconnect(IPCServer, SIGNAL(newConnection()), this, SLOT(NewConnection())); IPCSocket = IPCServer->nextPendingConnection(); if(!IPCSocket) return; m_connected = true; connect(IPCSocket, SIGNAL(disconnected()), this, SLOT(ClientDisconnect())); connect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead())); SendToClientFirst(); if(simultaneousRun()) { srvsList.removeOne(this); emit isReadyNow(); } }
SpotifyServer::SpotifyServer(QObject* parent) : AbstractMessageHandler<pb::spotify::Message>(NULL, parent), server_(new QTcpServer(this)), logged_in_(false) { connect(server_, SIGNAL(newConnection()), SLOT(NewConnection())); }
void ArduinoThread::run() { serv = new QTcpServer(this); connect(serv, SIGNAL(newConnection()), this, SLOT(NewConnection())); serv->listen(QHostAddress::Any, 34543); QProcess proc; proc.start("/sbin/ifconfig"); proc.waitForFinished(); QString ifconfigOutput = proc.readAllStandardOutput(); QString strAddress; QRegExp rx("addr:([^ ]+)"); int offset = 0; while(-1 != (rx.indexIn(ifconfigOutput, offset))) { offset += rx.matchedLength(); strAddress = "[" + rx.cap(1) + "]"; if(strAddress == "[127.0.0.1]") continue; if(!strAddress.contains(QRegExp("\\[\\d+\\.\\d+\\.\\d+\\.\\d+\\]"))) continue; break; } QUdpSocket *udpSocket = new QUdpSocket(this); udpSocket->writeDatagram(strAddress.toAscii(), QHostAddress::Broadcast, 12345); exec(); }
void TCPBase::RealStart() { connect(IPCServer, SIGNAL(newConnection()), this, SLOT(NewConnection())); IPCSocket = 0; #ifdef HWLIBRARY QThread *thread = new QThread; EngineInstance *instance = new EngineInstance; instance->port = IPCServer->serverPort(); instance->moveToThread(thread); connect(thread, SIGNAL(started()), instance, SLOT(start(void))); connect(instance, SIGNAL(finished()), thread, SLOT(quit())); connect(instance, SIGNAL(finished()), instance, SLOT(deleteLater())); connect(instance, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); #else QProcess * process; process = new QProcess(); connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(StartProcessError(QProcess::ProcessError))); QStringList arguments=getArguments(); #ifdef QT_DEBUG // redirect everything written on stdout/stderr process->setProcessChannelMode(QProcess::ForwardedChannels); #endif process->start(bindir->absolutePath() + "/hwengine", arguments); #endif m_hasStarted = true; }
NetworkFrontend::NetworkFrontend(QObject *parent, CardFactory *cardFactory) : QTcpServer(parent), Base(), cardFactory(cardFactory) { qDebug() << "NetworkFrontend : Constructeur" ; connect(this, SIGNAL(newConnection()), this, SLOT(NewConnection())); this->listen(QHostAddress::Any, 4242); qDebug() << "NetworkFrontend : Fin constructeur" ; }
void LocalRedirectServer::Listen() { server_->listen(QHostAddress::LocalHost); // We have to calculate this and store it now as the server port is cleared // once we close the socket. url_.setScheme("http"); url_.setHost("localhost"); url_.setPort(server_->serverPort()); url_.setPath("/"); connect(server_, SIGNAL(newConnection()), SLOT(NewConnection())); }
glgrServer::glgrServer(QObject *parent) : QTcpServer(parent) { setMaxPendingConnections(MAXCONN); connect(this, SIGNAL(newConnection()), this, SLOT(NewConnection())); s = NULL; bool ok = listen(QHostAddress::Any, PORT); if (!ok) { qWarning("glgrserver: Failed to listen to port %d", PORT); exit(1); } }
void Qserver::Connect() { server = new QLocalServer(this); connect(server, SIGNAL(newConnection()), this, SLOT(NewConnection())); if (!server->listen(name)) printf("server : ERROR LISTEN \n"); else printf("server : Server is OK \n"); }
void PanoServerTCP::Restart() { // Close running server. delete server_; server_ = new QTcpServer(); if (server_->listen(QHostAddress::Any, port_)) { log(QString("New Server - listing on TCP port ") + QString::number(port_)); } else { log("ERROR: Server failed to start!"); } connect(server_, SIGNAL(newConnection()), this, SLOT(NewConnection())); }
// ---------------------------------------------------------------------- /*virtual*/ void DServer::slotNewConnection() { QTcpSocket* pClientSocket = m_ptcpServer->nextPendingConnection(); connect(pClientSocket, SIGNAL(disconnected()), this, SLOT(deleteClientSocket()) ); connect(pClientSocket, SIGNAL(readyRead()), this, SLOT(slotReadClient()) ); pClientSockets.append(pClientSocket); sendMessageToSocket(pClientSocket, "Server Response: Connected!"); m_ptxt->append(QString::number( pClientSocket->localPort())+" is Connected"); emit NewConnection(); }
void CConnectionPool::Init(const std::string &host, const std::string &port, cb_InitConnection cb, int connection_count /*= 5*/, int connection_limit /*= 1*/) { //保存必要的信息 m_Host = host; m_Port = port; m_nConnectionLimit = connection_limit; //创建连接(池) for (int i = 0; i < connection_count; i++) { NewConnection(cb); } }
void OAuthenticator::StartAuthorisation() { server_.listen(QHostAddress::LocalHost); const quint16 port = server_.serverPort(); NewClosure(&server_, SIGNAL(newConnection()), this, SLOT(NewConnection())); QUrl url = QUrl(kGoogleOAuthEndpoint); url.addQueryItem("response_type", "code"); url.addQueryItem("client_id", kClientId); url.addQueryItem("redirect_uri", QString("http://localhost:%1").arg(port)); url.addQueryItem("scope", kGoogleOAuthScope); QDesktopServices::openUrl(url); }
void ConnectionManager::CreateConnection(const QSharedPointer<Edge> &pedge, const Id &rem_id) { QSharedPointer<Connection> con(new Connection(pedge, _local_id, rem_id), &QObject::deleteLater); con->SetSharedPointer(con); _con_tab.AddConnection(con); qDebug() << "Handle new connection:" << con->ToString(); QObject::connect(con.data(), SIGNAL(CalledDisconnect()), this, SLOT(HandleDisconnect())); QObject::connect(con.data(), SIGNAL(Disconnected(const QString &)), this, SLOT(HandleDisconnected(const QString &))); emit NewConnection(con); }
Connection* ConnectionFactoryCreate(Connection* factory, Address* address, aio4c_socket_t socket) { ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER; Connection* connection = NULL; void* data = NULL; connection = NewConnection(factory->pool, address, true); connection->socket = socket; #ifndef AIO4C_WIN32 if (fcntl(connection->socket, F_SETFL, O_NONBLOCK) == -1) { code.error = errno; code.connection = connection; Raise(AIO4C_LOG_LEVEL_ERROR, AIO4C_CONNECTION_ERROR_TYPE, AIO4C_FCNTL_ERROR, &code); shutdown(connection->socket, SHUT_RDWR); close(connection->socket); #else /* AIO4C_WIN32 */ unsigned long ioctl = 1; if (ioctlsocket(connection->socket, FIONBIO, &ioctl) != 0) { code.source = AIO4C_ERRNO_SOURCE_WSA; code.connection = connection; Raise(AIO4C_LOG_LEVEL_ERROR, AIO4C_CONNECTION_ERROR_TYPE, AIO4C_FCNTL_ERROR, &code); shutdown(connection->socket, SD_BOTH); closesocket(connection->socket); #endif /* AIO4C_WIN32 */ aio4c_free(connection); return NULL; } data = factory->dataFactory(connection, factory->dataFactoryArg); CopyEventQueue(connection->userHandlers, factory->userHandlers, data); CopyEventQueue(connection->systemHandlers, factory->systemHandlers, NULL); connection->closedBy[AIO4C_CONNECTION_OWNER_ACCEPTOR] = false; connection->closedBy[AIO4C_CONNECTION_OWNER_CLIENT] = true; return connection; } static void _ConnectionEventHandle(Connection* connection, Event event) { Log(AIO4C_LOG_LEVEL_DEBUG, "handling event %d for connection %s", event, connection->string); EventHandle(connection->systemHandlers, event, (EventSource)connection); EventHandle(connection->userHandlers, event, (EventSource)connection); }
void Network_Manager::ConnectToServer(char const* host, int port) { logWrite("Connecting to server %s:%d",host,port); Network_Connection* Connection = NewConnection(); Connection->socketHandle = -1; if (!Connection->Open(host, port)) { #ifdef WIN32 logWrite("Error while connecting to game server! (Code: %d)",GetLastError()); #else logWrite("Error while connecting to game server! (Code: %d)",errno); #endif return; } Game.IsHostingGame = false; IsServer = false; IsConnected = true; QueryServer(0); //Check protocol version //while (true) { //Frame(); //} }
void Network_Manager::StartServer(int port) { if (Connections.Count > 0) { //Close connections? logWrite("FIXME: A739C"); } logWrite("Starting game server on port %d",port); Network_Connection* ServerConnection = NewConnection(); ServerConnection->socketHandle = -1; if (!ServerConnection->Open(0, port)) { #ifdef WIN32 logWrite("Error while starting game server! (Code: %d)",GetLastError()); #else logWrite("Error while starting game server! (Code: %d)",errno); #endif IsServer = false; IsConnected = false; return; } Game.IsHostingGame = true; IsServer = true; IsConnected = false; }
void Server::ReceiveData( void ) { Conn *conn; struct sockaddr from_address; struct sockaddr_in *client_address; int num_bytes, actual_data_len; #ifdef __PLAT_NGC__ from_address.len = sizeof( sockaddr ); #else int addr_len = sizeof( from_address ); #endif // Local servers (i.e. non-network play) never really receive. Their data is automatically // "received" when the local client writes its data into the server's receive buffer transparently if( IsLocal()) { return; } do { num_bytes = recvfrom( m_socket, m_in_packet_buffer, Manager::vMAX_PACKET_SIZE, 0, &from_address, &addr_len ); if ( num_bytes < 0 )// == SOCKET_ERROR ) { #if defined( __PLAT_WN32__ ) || defined( __PLAT_XBOX__ ) if( WSAGetLastError() != WSAEWOULDBLOCK ) #else #ifdef __PLAT_NGPS__ if( sn_errno( m_socket ) != EWOULDBLOCK ) #else #ifdef __PLAT_NGC__ if( num_bytes != SO_EWOULDBLOCK ) #endif #endif #endif { #ifdef NET_DEBUG_MESSAGES Dbg_Printf( "Server Receive Error: " ); ReportError(); #endif } break; } else { #ifdef __PLAT_NGPS__ WaitSema( m_receive_semaphore_id ); #endif // __PLAT_NGPS__ m_TotalBytesIn += num_bytes; if( m_flags & App::mSECURE ) { actual_data_len = num_bytes - sizeof( unsigned short ); // subtract size of CRC } else { actual_data_len = num_bytes; } client_address = (struct sockaddr_in*) &from_address; //Dbg_Printf( "**** Received data from client 0x%x : %d, addr_len : %d\n", client_address->sin_addr.s_addr, //client_address->sin_port, addr_len ); conn = GetConnectionByAddress( client_address->sin_addr.s_addr, ntohs( client_address->sin_port )); if( conn ) { if( conn->IsValid() || (( m_flags & App::mSECURE ) == 0 )) { if( ( conn->m_read_ptr + actual_data_len ) < ( conn->m_read_buffer + Conn::vREAD_BUFFER_LENGTH )) { if( !validate_and_copy_stream( m_in_packet_buffer, conn->m_read_ptr, num_bytes )) { #ifdef __PLAT_NGPS__ SignalSema( m_receive_semaphore_id ); #endif // __PLAT_NGPS__ // If the game would like to handle this foreign data, allow it to do so now if( m_foreign_handler ) { m_foreign_handler( conn->m_read_ptr, num_bytes, &from_address ); } continue; } conn->m_read_ptr += actual_data_len; conn->GetInboundMetrics()->AddPacket( num_bytes + vUDP_PACKET_OVERHEAD, m_Timestamp ); conn->m_last_comm_time = Tmr::GetTime(); } } } else { Conn* foreign_conn; // Foreign connection. Create temporary connection to process this foreign message foreign_conn = NewConnection( client_address->sin_addr.s_addr, ntohs( client_address->sin_port ), Conn::mREMOTE | Conn::mFOREIGN ); if( foreign_conn ) { foreign_conn->m_app = this; if( !validate_and_copy_stream( m_in_packet_buffer, foreign_conn->m_read_ptr, num_bytes )) { #ifdef __PLAT_NGPS__ SignalSema( m_receive_semaphore_id ); #endif // __PLAT_NGPS__ // If the game would like to handle this foreign data, allow it to do so now if( m_foreign_handler ) { m_foreign_handler( m_in_packet_buffer, num_bytes, &from_address ); } delete foreign_conn; continue; } foreign_conn->m_read_ptr = foreign_conn->m_read_buffer + actual_data_len; foreign_conn->Invalidate(); } } #ifdef __PLAT_NGPS__ SignalSema( m_receive_semaphore_id ); #endif // __PLAT_NGPS__ } } while( num_bytes > 0 ); }
void ConnectionCommunity::OnWmCommandConnDialog(HWND hwnd, WPARAM wparam, LPARAM lparam, ConnectionInfo * dbname) { wyInt32 id; if(HIWORD(wparam) == EN_UPDATE) { id = LOWORD(wparam); if(id != IDC_DLGCONNECT_PASSWORD || (id == IDC_DLGCONNECT_PASSWORD && Button_GetCheck(GetDlgItem(hwnd, IDC_DLGCONNECT_STOREPASSWORD))== BST_CHECKED)) { EnableWindow(GetDlgItem(hwnd, IDC_SAVE), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_CLONECONN), FALSE); m_conndetaildirty = wyTrue; return; } } //handle connection name combobox /*else if(LOWORD(wparam) == IDC_DESC) { //if different connection is selected, then save the previous one if((HIWORD(wparam)== CBN_DROPDOWN) && (m_conndetaildirty == wyTrue)) { PostMessage(hwnd, SHOW_CONFIRM, 0, 0); m_conndetaildirty = wyFalse; } else if((HIWORD(wparam) == CBN_CLOSEUP) || (HIWORD(wparam) == CBN_SELENDOK)) { if((m_conndetaildirty == wyTrue) && (m_isnewconnection == wyTrue)) { SendMessage(GetDlgItem(hwnd, IDC_DESC), CB_DELETESTRING, m_newconnid, 0); m_conndetaildirty = wyFalse; m_isnewconnection = wyFalse; m_newconnid = -1; } //if connection is selected using keyboard or mouse, display the contents GetInitialDetails(hwnd); /* we have to change the tab selection to server also */ /*TabCtrl_SetCurSel(GetDlgItem(hwnd, IDC_CONNTAB), 0); ShowServerOptions(hwnd); m_conndetaildirty = wyFalse; return; } else if((HIWORD(wparam)== CBN_SELCHANGE)) { SetFocus(GetDlgItem(hwnd, IDC_DESC)); } }*/ //handle connection color combobox else if(LOWORD(wparam)== IDC_COLORCOMBO||LOWORD(wparam)== IDC_COLORCOMBO3) { if((HIWORD(wparam) == CBN_DROPDOWN) || (HIWORD(wparam)== CBN_SELCHANGE)) { //Command handler for color combo box OnWmCommandColorCombo(hwnd, wparam, lparam); dbname->m_rgbconn = m_rgbconnection; dbname->m_rgbfgconn = m_rgbconnectionfg; m_rgbobbkcolor = m_rgbconnection; m_rgbobfgcolor = m_rgbconnectionfg; //if color is changed in combo, then set m_conndetaildirty to true if((HIWORD(wparam)== CBN_SELCHANGE) && (m_conndetaildirty == wyFalse)) { if(m_changeobcolor == wyFalse) m_conndetaildirty = wyFalse; else m_conndetaildirty = wyTrue; } } if(m_conndetaildirty == wyTrue) { EnableWindow(GetDlgItem(hwnd, IDC_SAVE), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_CLONECONN), FALSE); dbname->m_rgbconn = m_rgbconnection; dbname->m_rgbfgconn = m_rgbconnectionfg; m_rgbobbkcolor = m_rgbconnection; m_rgbobfgcolor = m_rgbconnectionfg; } return; } //Handles the common option in 'MySQL' tab HandleCommonConnectOptions(hwnd, dbname, LOWORD(wparam)); switch(LOWORD(wparam)) { case IDOK: OnConnect(hwnd, dbname); break; case IDCANCEL: yog_enddialog(hwnd, 0); break; case IDC_DELETE: DeleteConnDetail(hwnd); break; case IDC_NEW: if(m_conndetaildirty == wyTrue) { PostMessage(hwnd, SHOW_CONFIRM, 0, 0); } m_conndetaildirty = wyFalse; NewConnection(hwnd); break; case IDC_SAVE: SaveConnection(hwnd); m_conndetaildirty = wyFalse; EnableWindow(GetDlgItem(hwnd, IDC_SAVE), FALSE); //EnableWindow(GetDlgItem(hwnd, IDC_CLONECONN), TRUE); break; case IDC_TESTCONN: OnTestConnection(hwnd); break; case IDC_CLONECONN: CloneConnection(hwnd); break; case IDC_TUNNELHELP: ShowHelp("http://sqlyogkb.webyog.com/article/155-connecting-using-http-tunneling"); break; case IDC_INITCOMMANDHELP: ShowHelp("http://sqlyogkb.webyog.com/article/158-advanced-connection-settings"); break; case IDC_SSHHELP: ShowHelp("http://sqlyogkb.webyog.com/article/154-connecting-using-ssh-tunneling"); break; case IDC_SSLHELP: ShowHelp("http://sqlyogkb.webyog.com/article/157-connecting-using-ssl-encryption"); break; case IDC_TIMEOUTHELP: case IDC_COMPRESSHELP: ShowHelp("http://sqlyogkb.webyog.com/article/153-direct-connection-using-mysql-c-api"); break; } }
int main() { // 通过T2SDK的引出函数,来获取一个新的CConfig对象 // 此对象在创建连接对象时被传递,用于配置所创建的连接对象的各种属性(比如服务器IP地址、安全模式) CConfigInterface * lpConfig = NewConfig(); // 通过T2SDK的引出函数NewXXXX返回的对象,需要调用对象的Release方法释放,而不能直接用delete // 因为t2sdk.dll和调用程序可能是由不同的编译器、编译模式生成,delete可能会导致异常 // 为了适应Delphi等使用(Delphi对接口自动调用AddRef方法),用C/C++开发的代码,需要在NewXXXX之后调用一下AddRef // 以保证引用计数正确 lpConfig->AddRef(); // [t2sdk] servers指定需要连接的IP地址及端口 lpConfig->SetString("t2sdk", "servers", "127.0.0.1:9004"); // [t2sdk] license_file指定许可证文件 lpConfig->SetString("t2sdk", "license_file", "license.dat"); // [t2sdk] send_queue_size指定T2_SDK的发送队列大小 lpConfig->SetString("t2sdk", "send_queue_size", "100"); //有名连接 lpConfig->SetString("t2sdk", "login_name", "xuxp"); // 通过T2SDK的引出函数,来获取一个新的CConnection对象 g_Connection = NewConnection(lpConfig); g_Connection->AddRef(); // 创建自定义类CCallback的对象(在初始化连接对象时需传递此对象,请看下面代码) CCallback callback; int ret = 0; // 初始化连接对象,返回0表示初始化成功,注意此时并没开始连接服务器,这里必须用Create2BizMsg,否则回调不成功 if (0 == (ret = g_Connection->Create2BizMsg(&callback))) { // 正式开始连接注册,参数1000为超时参数,单位是ms if (ret = g_Connection->Connect(1000)) { // 若连接/注册失败,打印失败原因 puts(g_Connection->GetErrorMsg(ret)); } else { //连接注册成功 puts("连接注册成功"); } } else { puts(g_Connection->GetErrorMsg(ret)); } // 通过getchar阻塞线程,等待服务端应答包到达 // 演示断开重连时,可在此时关闭服务器,然后再恢复 getchar(); // 释放资源 g_Connection->Release(); lpConfig->Release(); return 0; }
void UserProc::execute() { ArgList new_args; char **argv; char **argp; char **envp; sigset_t sigmask; MyString a_out_name; MyString shortname; int user_syscall_fd = -1; const int READ_END = 0; const int WRITE_END = 1; int pipe_fds[2]; FILE *cmd_fp; char buf[128]; ReliSock *new_reli = NULL; pipe_fds[0] = -1; pipe_fds[1] = -1; shortname.formatstr( "condor_exec.%d.%d", cluster, proc ); a_out_name.formatstr( "%s/%s/%s", Execute, local_dir, shortname.Value() ); // Set up arg vector according to class of job switch( job_class ) { case CONDOR_UNIVERSE_STANDARD: if( pipe(pipe_fds) < 0 ) { EXCEPT( "pipe()" );} dprintf( D_ALWAYS, "Pipe built\n" ); // The user process should not try to read commands from // 0, 1, or 2 since we'll be using the commands to redirect // those. if( pipe_fds[READ_END] < 14 ) { dup2( pipe_fds[READ_END], 14 ); close( pipe_fds[READ_END] ); pipe_fds[READ_END] = 14; } dprintf( D_ALWAYS, "New pipe_fds[%d,%d]\n", pipe_fds[0], pipe_fds[1] ); sprintf( buf, "%d", pipe_fds[READ_END] ); dprintf( D_ALWAYS, "cmd_fd = %s\n", buf ); new_args.AppendArg(shortname); new_args.AppendArg("-_condor_cmd_fd"); new_args.AppendArg(buf); break; case CONDOR_UNIVERSE_PVM: #if 1 EXCEPT( "Don't know how to deal with PVM jobs" ); #else new_args.AppendArg(shortname); new_args.AppendArg("-1"); new_args.AppendArg(in); new_args.AppendArg(out); new_args.AppendArg(err); #endif break; case CONDOR_UNIVERSE_VANILLA: if (privsep_enabled()) { EXCEPT("Don't know how to deal with Vanilla jobs"); } new_args.AppendArg(shortname.Value()); break; } new_args.AppendArgsFromArgList(args); // take care of USER_JOB_WRAPPER support_job_wrapper(a_out_name,&new_args); MyString exec_name; exec_name = a_out_name; // If privsep is turned on, then we need to use the PrivSep // Switchboard to launch the job // FILE* switchboard_in_fp; FILE* switchboard_err_fp; int switchboard_child_in_fd; int switchboard_child_err_fd; if (privsep_enabled()) { // create the pipes that we'll use to communicate // if (!privsep_create_pipes(switchboard_in_fp, switchboard_child_in_fd, switchboard_err_fp, switchboard_child_err_fd)) { EXCEPT("can't launch job: privsep_create_pipes failure"); } } argv = new_args.GetStringArray(); // Set an environment variable that tells the job where it may put scratch data // even if it moves to a different directory. // get the environment vector envp = env_obj.getStringArray(); // We may run more than one of these, so each needs its own // remote system call connection to the shadow if( job_class == CONDOR_UNIVERSE_PVM ) { new_reli = NewConnection( v_pid ); user_syscall_fd = new_reli->get_file_desc(); } // print out arguments to execve dprintf( D_ALWAYS, "Calling execve( \"%s\"", exec_name.Value() ); for( argp = argv; *argp; argp++ ) { // argv dprintf( D_ALWAYS | D_NOHEADER, ", \"%s\"", *argp ); } dprintf( D_ALWAYS | D_NOHEADER, ", 0" ); for( argp = envp; *argp; argp++ ) { // envp dprintf( D_ALWAYS | D_NOHEADER, ", \"%s\"", *argp ); } dprintf( D_ALWAYS | D_NOHEADER, ", 0 )\n" ); if( (pid = fork()) < 0 ) { EXCEPT( "fork" ); } if( pid == 0 ) { // the child // Block only these 3 signals which have special meaning for // checkpoint/restart purposes. Leave other signals ublocked // so that if we get an exception during the restart process, // we will get a core file to debug. sigemptyset( &sigmask ); // for some reason if we block these, the user process is unable // to unblock some or all of them. #if 0 sigaddset( &sigmask, SIGUSR1 ); sigaddset( &sigmask, SIGUSR2 ); sigaddset( &sigmask, SIGTSTP ); #endif sigprocmask( SIG_SETMASK, &sigmask, 0 ); // renice renice_self( "JOB_RENICE_INCREMENT" ); // make certain the syscall sockets which are being passed // to the user job are setup to be blocking sockets. this // is done by calling timeout(0) CEDAR method. // we must do this because the syscall lib does _not_ // expect to see any failures due to errno EAGAIN... if ( SyscallStream ) { SyscallStream->timeout(0); } if ( new_reli ) { new_reli->timeout(0); } // If I'm using privledge separation, connect to the procd. // we need to register a family with the procd for the newly // created process, so that the ProcD will allow us to send // signals to it // if (privsep_enabled() == true) { MyString procd_address; bool response; bool ret; ProcFamilyClient pfc; procd_address = get_procd_address(); ret = pfc.initialize(procd_address.Value()); if (ret == false) { EXCEPT("Failure to initialize the ProcFamilyClient object"); } ret = pfc.register_subfamily(getpid(), getppid(), 60, response); if (ret == false) { EXCEPT("Could not communicate with procd. Aborting."); } if (response == false) { EXCEPT("Procd refused to register job subfamily. Aborting."); } } // If there is a requested coresize for this job, enforce it. // Do it before the set_priv_final to ensure root can alter // the coresize to the requested amount. Otherwise, just // use whatever the current default is. if (coredump_limit_exists == TRUE) { limit( RLIMIT_CORE, coredump_limit, CONDOR_HARD_LIMIT, "max core size" ); } // child process should have only it's submitting uid, and cannot // switch back to root or some other uid. // It'd be nice to check for errors here, but // unfortunately, we can't, since this only returns the // previous priv state, not whether it worked or not. // -Derek Wright 4/30/98 set_user_priv_final(); switch( job_class ) { case CONDOR_UNIVERSE_STANDARD: // if we're using PrivSep, the chdir here could fail. instead, // we pass the job's IWD to the switchboard via pipe // if (!privsep_enabled()) { if( chdir(local_dir) < 0 ) { EXCEPT( "chdir(%s)", local_dir ); } } close( pipe_fds[WRITE_END] ); break; case CONDOR_UNIVERSE_PVM: if( chdir(local_dir) < 0 ) { EXCEPT( "chdir(%s)", local_dir ); } close( pipe_fds[WRITE_END] ); dup2( user_syscall_fd, RSC_SOCK ); break; case CONDOR_UNIVERSE_VANILLA: set_iwd(); open_std_file( 0 ); open_std_file( 1 ); open_std_file( 2 ); (void)close( RSC_SOCK ); (void)close( CLIENT_LOG ); break; } // Make sure we're not root if( getuid() == 0 ) { // EXCEPT( "We're about to start as root, aborting." ); // You can't see this error message at all. So, just // exit(4), which is what EXCEPT normally gives. exit( 4 ); } #if defined( LINUX ) && (defined(I386) || defined(X86_64)) // adjust the execution domain of the child to be suitable for // checkpointing. patch_personality(); #endif // if we're using privsep, we'll exec the PrivSep Switchboard // first, which is setuid; it will then setuid to the user we // give it and exec the real job // if (privsep_enabled()) { close(fileno(switchboard_in_fp)); close(fileno(switchboard_err_fp)); privsep_get_switchboard_command("exec", switchboard_child_in_fd, switchboard_child_err_fd, exec_name, new_args); deleteStringArray(argv); argv = new_args.GetStringArray(); } // Everything's ready, start it up... errno = 0; execve( exec_name.Value(), argv, envp ); // A successful call to execve() never returns, so it is an // error if we get here. A number of errors are possible // but the most likely is that there is insufficient swap // space to start the new process. We don't try to log // anything, since we have the UID/GID of the job's owner // and cannot write into the log files... exit( JOB_EXEC_FAILED ); } // The parent // PrivSep - we have at this point only spawned the switchboard // with the "exec" command. we need to use our pipe to it in // order to tell it how to execute the user job, and then use // the error pipe to make sure everything worked // if (privsep_enabled()) { close(switchboard_child_in_fd); close(switchboard_child_err_fd); privsep_exec_set_uid(switchboard_in_fp, uid); privsep_exec_set_path(switchboard_in_fp, exec_name.Value()); privsep_exec_set_args(switchboard_in_fp, new_args); privsep_exec_set_env(switchboard_in_fp, env_obj); privsep_exec_set_iwd(switchboard_in_fp, local_dir); privsep_exec_set_inherit_fd(switchboard_in_fp, pipe_fds[0]); privsep_exec_set_inherit_fd(switchboard_in_fp, RSC_SOCK); privsep_exec_set_inherit_fd(switchboard_in_fp, CLIENT_LOG); privsep_exec_set_is_std_univ(switchboard_in_fp); fclose(switchboard_in_fp); if (!privsep_get_switchboard_response(switchboard_err_fp)) { EXCEPT("error starting job: " "privsep get_switchboard_response failure"); } } dprintf( D_ALWAYS, "Started user job - PID = %d\n", pid ); if( job_class != CONDOR_UNIVERSE_VANILLA ) { // Send the user process its startup environment conditions close( pipe_fds[READ_END] ); cmd_fp = fdopen( pipe_fds[WRITE_END], "w" ); dprintf( D_ALWAYS, "cmd_fp = %p\n", cmd_fp ); if( is_restart() ) { #if 1 fprintf( cmd_fp, "restart\n" ); dprintf( D_ALWAYS, "restart\n" ); #else fprintf( cmd_fp, "restart %s\n", target_ckpt ); dprintf( D_ALWAYS, "restart %s\n", target_ckpt ); #endif fprintf( cmd_fp, "end\n" ); dprintf( D_ALWAYS, "end\n" ); } else { fprintf( cmd_fp, "end\n" ); dprintf( D_ALWAYS, "end\n" ); } fclose( cmd_fp ); } deleteStringArray(argv); deleteStringArray(envp); state = EXECUTING; if( new_reli ) { delete new_reli; } // removed some vanilla-specific code here // ASSERT(job_class != CONDOR_UNIVERSE_VANILLA); }
int cOpenHpiDaemon::MainLoop() { DbgCon( "ready for incomming connections.\n" ); int num_add = 1; if ( m_interactive ) { m_pollfd = new pollfd[2]; num_add++; m_pollfd[1].fd = 0; // stdin m_pollfd[1].events = POLLIN; m_pollfd[1].revents = 0; } else m_pollfd = new pollfd[1]; m_pollfd[0].fd = m_main_socket->m_fd; m_pollfd[0].events = POLLIN; m_pollfd[0].revents = 0; while( true ) { int rv = poll( m_pollfd, m_num_connections + num_add, 250 ); if ( rv < 0 ) { usleep( 100000 ); if ( errno != EINTR ) fprintf( stderr, "can't poll: %s %d !\n", strerror( errno ), errno ); // sleep a while usleep( 100 ); continue; } if ( rv == 0 ) { Idle(); continue; } for( int i = m_num_connections - 1; i >= 0; i-- ) if ( m_pollfd[i].revents ) if ( !HandleData( m_connections[i] ) ) { CloseConnection( i ); // m_pollfd has changed continue; } if ( m_pollfd[m_num_connections].revents ) { // create new connection cServerConnection *c = ServerConnectionMainAccept( m_main_socket ); if ( c ) { NewConnection( c ); continue; } } if ( m_interactive && m_pollfd[m_num_connections+1].revents ) if ( HandleInteractive() == false ) break; } return 0; }
static int BindListenOnPort( #ifndef _WIN32 sa_family_t addr_type, size_t addr_size, #else short addr_type, int addr_size, #endif void *pServ_addr, ber_socket_t *pSockfd ) { #define LDAP_PORT_LISTEN_BACKLOG 128 int optname = 0; int retVal = LDAP_SUCCESS; int retValBind = 0; PSTR pszLocalErrMsg = NULL; int on = 1; #ifdef _WIN32 DWORD sTimeout = 0; int reTries = 0; #else struct timeval sTimeout = {0}; #endif *pSockfd = -1; *pSockfd = socket(addr_type, SOCK_STREAM, 0); if (*pSockfd < 0) { #ifdef _WIN32 errno = WSAGetLastError(); #endif retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "%s: socket() call failed with errno: %d", __func__, errno ); } #ifdef _WIN32 optname = SO_EXCLUSIVEADDRUSE; #else optname = SO_REUSEADDR; #endif if (setsockopt(*pSockfd, SOL_SOCKET, optname, (const char *)(&on), sizeof(on)) < 0) { #ifdef _WIN32 errno = WSAGetLastError(); #endif retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "%s: setsockopt() call failed with errno: %d", __func__, errno ); } on = 1; // turn on TCP_NODELAY below if (setsockopt(*pSockfd, IPPROTO_TCP, TCP_NODELAY, (const char *)(&on), sizeof(on) ) < 0) { #ifdef _WIN32 errno = WSAGetLastError(); #endif retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "%s: setsockopt() TCP_NODELAY call failed with errno: %d", __func__, errno ); } if (addr_type == AF_INET6) { #ifdef _WIN32 if (setsockopt(*pSockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)(&on), sizeof(on) ) < 0) { errno = WSAGetLastError(); #else if (setsockopt(*pSockfd, SOL_IPV6, IPV6_V6ONLY, (const char *)(&on), sizeof(on) ) < 0) { #endif retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "%s: setsockopt() IPV6_V6ONLY call failed with errno: %d", __func__, errno ); } } if (gVmdirGlobals.dwLdapRecvTimeoutSec > 0) { #ifdef _WIN32 sTimeout = gVmdirGlobals.dwLdapRecvTimeoutSec*1000; #else sTimeout.tv_sec = gVmdirGlobals.dwLdapRecvTimeoutSec; sTimeout.tv_usec = 0; #endif if (setsockopt(*pSockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &sTimeout, sizeof(sTimeout)) < 0) { #ifdef _WIN32 errno = WSAGetLastError(); #endif retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "%s: setsockopt() SO_RCVTIMEO failed, errno: %d", __func__, errno ); } } retValBind = bind(*pSockfd, (struct sockaddr *) pServ_addr, addr_size); #ifdef _WIN32 // Add retry logic per PR 1347783 reTries = 0; while (retValBind != 0 && reTries < MAX_NUM_OF_BIND_PORT_RETRIES) { errno = WSAGetLastError(); if (errno != WSAEADDRINUSE) { break; } reTries++; VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "%s: bind() call failed with errno: %d, re-trying (%d)", __func__, errno, reTries); VmDirSleep(1000); retValBind = bind(*pSockfd, (struct sockaddr *) pServ_addr, addr_size); } #endif if (retValBind != 0) { retVal = LDAP_OPERATIONS_ERROR; //need to free socket ... BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "%s: bind() call failed with errno: %d", __func__, errno ); } if (listen(*pSockfd, LDAP_PORT_LISTEN_BACKLOG) != 0) { #ifdef _WIN32 errno = WSAGetLastError(); #endif retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "%s: listen() call failed with errno: %d", __func__, errno ); } cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return retVal; error: if (*pSockfd >= 0) { tcp_close(*pSockfd); *pSockfd = -1; } VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, VDIR_SAFE_STRING(pszLocalErrMsg)); goto cleanup; } /* * We own pConnection and delete it when done. */ static DWORD ProcessAConnection( PVOID pArg ) { VDIR_CONNECTION *pConn = NULL; int retVal = LDAP_SUCCESS; ber_tag_t tag = LBER_ERROR; ber_len_t len = 0; BerElement * ber = NULL; ber_int_t msgid = -1; PVDIR_OPERATION pOperation = NULL; int reTries = 0; BOOLEAN bDownOpThrCount = FALSE; PVDIR_CONNECTION_CTX pConnCtx = NULL; // increment operation thread counter retVal = VmDirSyncCounterIncrement(gVmdirGlobals.pOperationThrSyncCounter); BAIL_ON_VMDIR_ERROR(retVal); bDownOpThrCount = TRUE; pConnCtx = (PVDIR_CONNECTION_CTX)pArg; assert(pConnCtx); retVal = NewConnection(pConnCtx->sockFd, &pConn, pConnCtx->pSockbuf_IO); if (retVal != LDAP_SUCCESS) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: NewConnection [%d] failed with error: %d", __func__, pConnCtx->sockFd, retVal); goto error; } while (TRUE) { if (VmDirdState() == VMDIRD_STATE_SHUTDOWN) { goto cleanup; } ber = ber_alloc(); assert( ber != NULL); /* An LDAP request message looks like: * LDAPMessage ::= SEQUENCE { * messageID MessageID, * protocolOp CHOICE { * bindRequest BindRequest, * unbindRequest UnbindRequest, * searchRequest SearchRequest, * ... }, * controls [0] Controls OPTIONAL } */ // reset retry count reTries = 0; // Read complete LDAP request message (tag, length, and real message). while( reTries < MAX_NUM_OF_SOCK_READ_RETRIES ) { if ((tag = ber_get_next( pConn->sb, &len, ber )) == LDAP_TAG_MESSAGE ) { break; } #ifdef _WIN32 // in ber_get_next (liblber) call, sock_errset() call WSASetLastError() errno = WSAGetLastError(); if ( errno == EWOULDBLOCK || errno == EAGAIN || errno == WSAETIMEDOUT) #else if ( errno == EWOULDBLOCK || errno == EAGAIN) #endif { if (gVmdirGlobals.dwLdapRecvTimeoutSec > 0 && ber->ber_len == 0) { VMDIR_LOG_INFO( LDAP_DEBUG_CONNS, "%s: disconnecting peer (%s), idle > %d seconds", __func__, pConn->szClientIP, gVmdirGlobals.dwLdapRecvTimeoutSec); retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR( retVal ); } //This may occur when not all data have recieved - set to EAGAIN/EWOULDBLOCK by ber_get_next, // and in such case ber->ber_len > 0; if (reTries > 0 && reTries % 5 == 0) { VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "%s: ber_get_next() failed with errno = %d, peer (%s), re-trying (%d)", __func__, errno , pConn->szClientIP, reTries); } VmDirSleep(200); reTries++; continue; } // Unexpected error case. if (errno == 0) { VMDIR_LOG_INFO( LDAP_DEBUG_CONNS, "%s: ber_get_next() peer (%s) disconnected", __func__, pConn->szClientIP); } else { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: ber_get_next() call failed with errno = %d peer (%s)", __func__, errno, pConn->szClientIP); } retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR( retVal ); } // Read LDAP request messageID (tag, length (not returned since it is implicit/integer), and messageID value) if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ProcessAConnection: ber_get_int() call failed." ); retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR( retVal ); } // Read protocolOp (tag) and length of the LDAP operation message, and leave the pointer at the beginning // of the LDAP operation message (to be parsed by PerformXYZ methods). if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ProcessAConnection: ber_peek_tag() call failed." ); retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR( retVal ); } retVal = VmDirNewOperation(ber, msgid, tag, pConn, &pOperation); if (retVal) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ProcessAConnection: NewOperation() call failed." ); retVal = LDAP_OPERATIONS_ERROR; } BAIL_ON_VMDIR_ERROR( retVal ); // // If this is a multi-stage operation don't overwrite the start time if it's already set. // pConn->SuperLogRec.iStartTime = pConn->SuperLogRec.iStartTime ? pConn->SuperLogRec.iStartTime : VmDirGetTimeInMilliSec(); switch (tag) { case LDAP_REQ_BIND: retVal = VmDirPerformBind(pOperation); if (retVal != LDAP_SASL_BIND_IN_PROGRESS) { _VmDirCollectBindSuperLog(pConn, pOperation); // ignore error } break; case LDAP_REQ_ADD: retVal = VmDirPerformAdd(pOperation); break; case LDAP_REQ_SEARCH: retVal = VmDirPerformSearch(pOperation); break; case LDAP_REQ_UNBIND: retVal = VmDirPerformUnbind(pOperation); break; case LDAP_REQ_MODIFY: retVal = VmDirPerformModify(pOperation); break; case LDAP_REQ_DELETE: retVal = VmDirPerformDelete(pOperation); break; case LDAP_REQ_MODDN: case LDAP_REQ_COMPARE: case LDAP_REQ_ABANDON: case LDAP_REQ_EXTENDED: VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "ProcessAConnection: Operation is not yet implemented.." ); pOperation->ldapResult.errCode = retVal = LDAP_UNWILLING_TO_PERFORM; // ignore following VmDirAllocateStringA error. VmDirAllocateStringA( "Operation is not yet implemented.", &pOperation->ldapResult.pszErrMsg); VmDirSendLdapResult( pOperation ); break; default: pOperation->ldapResult.errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; break; } pConn->SuperLogRec.iEndTime = VmDirGetTimeInMilliSec(); VmDirOPStatisticUpdate(tag, pConn->SuperLogRec.iEndTime - pConn->SuperLogRec.iStartTime); if (tag != LDAP_REQ_BIND) { VmDirLogOperation(gVmdirGlobals.pLogger, tag, pConn, pOperation->ldapResult.errCode); _VmDirScrubSuperLogContent(tag, &pConn->SuperLogRec); } VmDirFreeOperation(pOperation); pOperation = NULL; ber_free( ber, 1); ber = NULL; if (retVal == LDAP_NOTICE_OF_DISCONNECT) // returned as a result of protocol parsing error. { // RFC 4511, section 4.1.1: If the server receives an LDAPMessage from the client in which the LDAPMessage // SEQUENCE tag cannot be recognized, the messageID cannot be parsed, the tag of the protocolOp is not // recognized as a request, or the encoding structures or lengths of data fields are found to be incorrect, // then the server **SHOULD** return the Notice of Disconnection, with the resultCode // set to protocolError, and **MUST** immediately terminate the LDAP session as described in Section 5.3. goto cleanup; } } cleanup: if (retVal == LDAP_NOTICE_OF_DISCONNECT) { // Optionally send Notice of Disconnection with rs->err. } if (ber != NULL) { ber_free( ber, 1 ); } VmDirDeleteConnection(&pConn); VMDIR_SAFE_FREE_MEMORY(pConnCtx); VmDirFreeOperation(pOperation); if (bDownOpThrCount) { VmDirSyncCounterDecrement(gVmdirGlobals.pOperationThrSyncCounter); } _VmDirFlowCtrlThrExit(); // TODO: should we return dwError ? return 0; error: goto cleanup; }
ServerModel::ServerModel() : m_nextBlockSize(0) { m_clients.clear(); connect(this, SIGNAL(newConnection()), this, SLOT(NewConnection())); }
int main() { // 通过T2SDK的引出函数,来获取一个新的CConfig对象 // 此对象在创建连接对象时被传递,用于配置所创建的连接对象的各种属性(比如服务器IP地址、安全模式) CConfigInterface * lpConfig = NewConfig(); // 通过T2SDK的引出函数NewXXXX返回的对象,需要调用对象的Release方法释放,而不能直接用delete // 因为t2sdk.dll和调用程序可能是由不同的编译器、编译模式生成,delete可能会导致异常 // 为了适应Delphi等使用(Delphi对接口自动调用AddRef方法),用C/C++开发的代码,需要在NewXXXX之后调用一下AddRef // 以保证引用计数正确 lpConfig->AddRef(); // [t2sdk] servers指定需要连接的IP地址及端口 lpConfig->SetString("t2sdk", "servers", "192.168.94.30:9999"); // [t2sdk] license_file指定许可证文件 lpConfig->SetString("t2sdk", "license_file", "license.dat"); // [t2sdk] send_queue_size指定T2_SDK的发送队列大小 lpConfig->SetString("t2sdk", "send_queue_size", "100"); //在此设置一下就可以支持自动重连 lpConfig->SetString("t2sdk", "auto_reconnect", "1"); // 通过T2SDK的引出函数,来获取一个新的CConnection对象 g_Connection = NewConnection(lpConfig); g_Connection->AddRef(); // 创建自定义类CCallback的对象(在初始化连接对象时需传递此对象,请看下面代码) CCallback callback; int ret = 0; // 初始化连接对象,返回0表示初始化成功,注意此时并没开始连接服务器 if (0 == (ret = g_Connection->Create(&callback))) { // 正式开始连接注册,参数1000为超时参数,单位是ms if (ret = g_Connection->Connect(1000)) { // 若连接/注册失败,打印失败原因 puts(g_Connection->GetErrorMsg(ret)); } else { // 演示如何使用打包器 IF2Packer *lpPacker = NewPacker(2); lpPacker->AddRef(); lpPacker->BeginPack(); lpPacker->AddField("Field"); lpPacker->AddStr("Data"); lpPacker->EndPack(); // 异步模式收发包,第三个参数填1 g_Connection->SendBiz(100, lpPacker, 1); // 释放打包器,不释放会引起内存泄露,后果严重 lpPacker->FreeMem(lpPacker->GetPackBuf()); lpPacker->Release(); } } else { puts(g_Connection->GetErrorMsg(ret)); } // 通过getchar阻塞线程,等待服务端应答包到达 // 演示断开重连时,可在此时关闭服务器,然后再恢复 getchar(); // 释放资源 g_Connection->Release(); lpConfig->Release(); return 0; }
Connection *SocTransport::AsyncConnect(NetAddress *pnad) { MpTrace("AsyncConnect(%s)", pnad != NULL ? inet_ntoa(((sockaddr_in *)pnad)->sin_addr) : "loopback"); Connection *pcon; // A NULL pnad means this device is the server and is now trying to // connect to itself as a client. Use the LoopbackConnection to satisfy // this. if (pnad == NULL) { pcon = new LoopbackConnection(this); Assert(pcon != NULL, "out of memory!"); if (pcon == NULL) return NULL; m_fAsyncConnectLoopback = true; } else { // Create the socket for connecting to the server SOCKET soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (soc == INVALID_SOCKET) { #ifdef DEBUG HostMessageBox(TEXT("socket err: 0x%lx"), PszFromSocError()); #endif return NULL; } // Disable nagle algorithm int nTrue = 1; setsockopt(soc, IPPROTO_TCP, TCP_NODELAY, (NetBuff)&nTrue, sizeof(int)); // Disable excessive 'lingering' (particularly a problem on PalmOS <=5 which has only 16 sockets) linger lngr; lngr.l_onoff = 1; lngr.l_linger = 0; setsockopt(soc, SOL_SOCKET, SO_LINGER, (NetBuff)&lngr, sizeof(lngr)); // Connect to the server // UNDONE: On PalmOS <=5 this occasionally times out after 2 secs. Longer would be better if (connect(soc, (const sockaddr *)pnad, sizeof(sockaddr_in)) != 0) { switch (WSAGetLastError()) { case WSAEHOSTUNREACH: HtMessageBox(kfMbWhiteBorder, "Comm Problem", "Host unreachable."); break; case WSAECONNREFUSED: HtMessageBox(kfMbWhiteBorder, "Comm Problem", "Connection refused."); break; case WSAETIMEDOUT: HtMessageBox(kfMbWhiteBorder, "Comm Problem", "Timed out trying to connect to host."); break; default: HtMessageBox(kfMbWhiteBorder, "Comm Problem", "Unable to connect. Error %d", WSAGetLastError()); break; } closesocket(soc); return NULL; } pcon = NewConnection(soc); if (pcon == NULL) { closesocket(soc); return NULL; } m_fAsyncConnectLoopback = false; } AddConnection(pcon); Assert(m_pconAsyncConnect == NULL, "Can only have one pending AsyncConnect at a time"); m_pconAsyncConnect = pcon; return pcon; }