int tclcommand_imd_print_check_connect(Tcl_Interp *interp) { /* handshaking */ if (vmdsock_selread(initsock, 0) > 0) { int32_t length; sock = vmdsock_accept(initsock); if (imd_handshake(sock)) { Tcl_AppendResult(interp, "IMD handshake failed. Wrong VMD version ?", (char *) NULL); vmdsock_destroy(sock); sock = 0; return (TCL_ERROR); } sleep(1); if ((vmdsock_selread(sock, 0) != 1) || (imd_recv_header(sock, &length) != IMD_GO)) { Tcl_AppendResult(interp, "No go from VMD. Wrong VMD version ?", (char *) NULL); vmdsock_destroy(sock); sock = 0; return (TCL_ERROR); } sleep(1); } return (TCL_OK); }
void IMD::connect(){ if(comm.Get_rank()==0) { if(wait && clientsock==NULL) fprintf(stderr,"Waiting for IMD connection on %s:%d...\n", host.c_str(), port); do{ if (vmdsock_selread(sock,00) > 0) { clientsock = vmdsock_accept(sock); if (imd_handshake(clientsock)) { clientsock = NULL; }; sleep(1); int length; if(clientsock){ if (vmdsock_selread(clientsock, 0) != 1 || imd_recv_header(clientsock, &length) != IMD_GO) { clientsock = NULL; } } } } while(wait && clientsock==NULL); connected=(clientsock!=NULL); int c=connected; comm.Bcast(&c,1,0); } else { int c; comm.Bcast(&c,1,0); connected=c; } }
void IMDSimBlocking::update() { if (!isConnected()) return; IMDType type; int32 length; while (isConnected() && vmdsock_selread(sock,0)) { type = imd_recv_header(sock, &length); switch (type) { case IMD_FCOORDS: process_coordinates(length); break; case IMD_ENERGIES: process_energies(length); break; case IMD_MDCOMM: process_mdcomm(length); break; case IMD_IOERROR: disconnect(); break; default: break; // Don't need to read data } } }
int VMDCollab::check_event() { if (!clientsock) return FALSE; eval_in_progress = TRUE; char buf[VMDCOLLAB_MSGSIZE]; while (vmdsock_selread(clientsock, 0) > 0) { if (imd_readn(clientsock, buf, VMDCOLLAB_MSGSIZE) != VMDCOLLAB_MSGSIZE) { vmdsock_shutdown(clientsock); vmdsock_destroy(clientsock); clientsock = NULL; break; } runcommand(new TclEvalEvent(buf)); } eval_in_progress = FALSE; return TRUE; }
int imd_recv_handshake(void *s) { int32_t buf; IMDType type; /* Wait 5 seconds for the handshake to come */ if (vmdsock_selread(s, 5) != 1) return -1; /* Check to see that a valid handshake was received */ type = imd_recv_header_nolengthswap(s, &buf); if (type != IMD_HANDSHAKE) return -1; /* Check its endianness, as well as the IMD version. */ if (buf == IMDVERSION) { if (!imd_go(s)) return 0; return -1; } swap4((char *)&buf, 4); if (buf == IMDVERSION) { if (!imd_go(s)) return 1; } /* We failed to determine endianness. */ return -1; }
int tclcommand_imd_print_drain_socket(Tcl_Interp *interp) { while (vmdsock_selread(sock,0) > 0) { int32_t length; IMDType type = imd_recv_header(sock, &length); switch (type) { case IMD_MDCOMM: /* ignore forces for now */ Tcl_AppendResult(interp, "IMD force feedback not yet implemented", (char *) NULL); return (TCL_ERROR); /* Expect the msglength to give number of indicies, and the data message to consist of first the indicies, then the coordinates in xyz1 xyz2... format. int32_t *addindices = new int32_t[length]; float *addforces = new float[3*length]; if (imd_recv_mdcomm(sock, length, addindices, addforces)) throw Error(IOERROR); oversized tmp buffer int32_t *tmpindices = new int32_t[n_atoms + length]; float *tmpforces = new float[3*(n_atoms + length)]; int32_t tmpatoms = n_atoms; for (int i = 0; i < tmpatoms; i++) { tmpindices[i] = indices[i]; tmpforces[3*i ] = forces[3*i]; tmpforces[3*i + 1] = forces[3*i + 1]; tmpforces[3*i + 2] = forces[3*i + 2]; } for (int i = 0; i < length; i++) { int32_t index = addindices[i]; check if there is a force for this atom already int j; for (j = 0; j < tmpatoms; j++) if (tmpindices[j] == index) break; if (j == tmpatoms) { tmpindices[j] = index; tmpatoms++; } tmpforces[3*j ] = addforces[3*i ]; tmpforces[3*j + 1] = addforces[3*i + 1]; tmpforces[3*j + 2] = addforces[3*i + 2]; } if (n_atoms > 0) { delete[] indices; delete[] forces; } n_atoms = tmpatoms; indices = new int32_t[n_atoms]; forces = new float[3*n_atoms]; cout << "now forces are" << endl; for (int i = 0; i < n_atoms; i++) { indices[i] = tmpindices[i]; forces[3*i ] = tmpforces[3*i]; forces[3*i + 1] = tmpforces[3*i + 1]; forces[3*i + 2] = tmpforces[3*i + 2]; cout << indices[i] << " force " << forces[3*i ] << " " << forces[3*i + 1] << " " << forces[3*i + 2] << endl; } cout << "end" << endl; */ break; case IMD_TRATE: transfer_rate = length; break; case IMD_IOERROR: vmdsock_destroy(sock); sock = 0; Tcl_AppendResult(interp, "IMD reports IO error", (char *) NULL); return (TCL_ERROR); case IMD_DISCONNECT: case IMD_KILL: vmdsock_destroy(sock); sock = 0; Tcl_AppendResult(interp, "no connection", (char *) NULL); return (TCL_OK); case IMD_ENERGIES: case IMD_FCOORDS: Tcl_AppendResult(interp, "IMD protocol failure: unexpected token.", (char *) NULL); return (TCL_ERROR); break; default: ; } } return (TCL_OK); }
void *VMDCollab::serverproc(void *serversock) { ResizeArray<void *>clients; char buf[VMDCOLLAB_MSGSIZE]; int i, j; while (1) { // if we have no clients, hang until someone connects // otherwise, just check for pending connections if (vmdsock_selread(serversock, 0) > 0) { msgInfo << "serversock became readable" << sendmsg; void *clientsock = vmdsock_accept(serversock); if (clientsock) { msgInfo << "VMDCollab accepting connection" << sendmsg; clients.append(clientsock); } } else if (vmdsock_selwrite(serversock, 0)) { msgInfo << "serversock became writable; exiting..." << sendmsg; break; } // Loop through one socket at a time. If incoming data is found, // drain it before moving on, on the assumption that we only want // commands from one VMD at a time to be propagated to the other // clients. for (i=0; i<clients.num(); i++) { void *client = clients[i]; while (vmdsock_selread(client, 0) > 0) { memset(buf, 0, VMDCOLLAB_MSGSIZE); if (imd_readn(client, buf, VMDCOLLAB_MSGSIZE) != VMDCOLLAB_MSGSIZE) { msgInfo << "client sent incomplete message, shutting it down" << sendmsg; vmdsock_shutdown(client); vmdsock_destroy(client); clients.remove(clients.find(client)); break; } // send to all other clients for (j=0; j<clients.num(); j++) { void *dest = clients[j]; if (dest != client) { imd_writen(clients[j], buf, VMDCOLLAB_MSGSIZE); } } // loop over clients other than sender } // while client is readable } // loop over clients vmd_msleep(10); } // if here, then the serversock got shut down, indicating that it's // time to die. msgInfo << "VMDCollab shutting down server" << sendmsg; for (i=0; i<clients.num(); i++) { void *client = clients[i]; strcpy(buf, "exit"); imd_writen(client, buf, VMDCOLLAB_MSGSIZE); vmdsock_shutdown(client); vmdsock_destroy(client); } vmdsock_destroy(serversock); return NULL; }
void IMD::receive(){ if(!connected) return; if(clientsock){ IMDType type; int length; int itype; while (vmdsock_selread(clientsock,0) > 0) { type = imd_recv_header(clientsock, &length); if(type==IMD_MDCOMM){ int32* vmd_atoms = new int32[length]; float* vmd_forces = new float[3*length]; imd_recv_mdcomm(clientsock, length, vmd_atoms, vmd_forces); for(int i=0;i<length;i++){ forces[3*vmd_atoms[i]+0]=vmd_forces[3*i+0]; forces[3*vmd_atoms[i]+1]=vmd_forces[3*i+1]; forces[3*vmd_atoms[i]+2]=vmd_forces[3*i+2]; } delete [] vmd_atoms; delete [] vmd_forces; itype=0; comm.Bcast(&itype,1,0); comm.Bcast(&forces[0],forces.size(),0); }else if(type==IMD_DISCONNECT){ vmdsock_destroy(clientsock); clientsock=NULL; for(unsigned i=0;i<forces.size();i++) forces[i]=0.0; connected=false; itype=1; comm.Bcast(&itype,1,0); break; }else if(type==IMD_TRATE){ if(length<1) length=1; itype=2; log.printf("IMD: setting transfer rate to %d\n",length); transferRate=length; comm.Bcast(&itype,1,0); comm.Bcast(&transferRate,1,0); }else if(type==IMD_KILL){ log.printf("IMD: killing simulation\n"); itype=3; comm.Bcast(&itype,1,0); plumed.exit(); } } itype=-1; comm.Bcast(&itype,1,0); } if(comm.Get_rank()!=0){ int itype; while(true){ comm.Bcast(&itype,1,0); if(itype==-1)break; else if(itype==0) comm.Bcast(&forces[0],forces.size(),0); else if(itype==1) { for(unsigned i=0;i<forces.size();i++) forces[i]=0.0; connected=false; } else if(itype==2) comm.Bcast(&transferRate,1,0); else if(itype==3) plumed.exit(); else plumed_error(); } } }