socket.cpp

来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C++ 代码 · 共 558 行 · 第 1/2 页

CPP
558
字号
}void Socket::writeflush(){#ifndef UNBUFFERED_WRITES  Write(writebuffer.data(),writebuffer.size());  writebuffer.resize(0);#endif}string Socket::ErrorString(){#ifdef __MINGW32__  int e=WSAGetLastError();  switch(e){  case WSAEACCES:return "Permission denied";  case WSAEADDRINUSE:return "Address already in use";  case WSAEADDRNOTAVAIL:return "Cannot assign requested address";  case WSAEAFNOSUPPORT:    return "Address family not supported by protocol family";  case WSAEALREADY:return "Operation already in progress";  case WSAECONNABORTED:return "Software caused connection abort";  case WSAECONNREFUSED:return "Connection refused";  case WSAECONNRESET:return "Connection reset by peer";  case WSAEDESTADDRREQ:return "Destination address required";  case WSAEFAULT:return "Bad address)";  case WSAEHOSTDOWN:return "Host is down";  case WSAEHOSTUNREACH:return "No route to host";  case WSAEINPROGRESS:return "Operation now in progress";  case WSAEINTR:return "Interrupted function call";  case WSAEINVAL:return "Invalid argument";  case WSAEISCONN:return "Socket is already connected";  case WSAEMFILE:return "Too many open files";  case WSAEMSGSIZE:return "Message too long";  case WSAENETDOWN:return "Network is down";  case WSAENETRESET:return "Network dropped connection on reset";  case WSAENETUNREACH:return "Network is unreachable";  case WSAENOBUFS:return "No buffer space available";  case WSAENOPROTOOPT:return "Bad protocol option";  case WSAENOTCONN:return "Socket is not connected";  case WSAENOTSOCK:return "Socket operation on non-socket";  case WSAEOPNOTSUPP:return "Operation not supported";  case WSAEPFNOSUPPORT:return "Protocol family not supported";  case WSAEPROCLIM:return "Too many processes";  case WSAEPROTONOSUPPORT:return "Protocol not supported";  case WSAEPROTOTYPE:return "Protocol wrong type for socket";  case WSAESHUTDOWN:return "Cannot send after socket shutdown";  case WSAESOCKTNOSUPPORT:return "Socket type not supported";  case WSAETIMEDOUT:return "Connection timed out";  case WSAEWOULDBLOCK:return "Resource temporarily unavailable";  case WSAHOST_NOT_FOUND:return "Host not found";  case WSANOTINITIALISED:return "Successful WSAStartup not yet performed";  case WSANO_DATA:return "Valid name, no data record of requested type";  case WSANO_RECOVERY:return "This is a non-recoverable error";  case WSASYSNOTREADY:return "Network subsystem is unavailable";  case WSATRY_AGAIN:return "Non-authoritative host not found";  case WSAVERNOTSUPPORTED:return "WINSOCK.DLL version out of range";  case WSAEDISCON:return "Graceful shutdown in progress";  default:return string("Unknown error (") + tostring(e) + ")";  }#else // __MINGW32__  return strerror(errno);#endif // __MINGW32__}void Socket::writestring(const string s){#ifdef SOCKET_DEBUG  printf("Socket::writestring: writing string \"%s\"\n",s.c_str());#endif  // Adds string length before the string itself.  unsigned int size=s.size();#ifdef SOCKET_STRINGS  // We also transmit the length of the string as a string (of fixed  // length) to make it totally portable.  if(size>999999) throw string("Socket::writestring: string too long");  char length[7];  sprintf(length,"%06i",size);  bufferedwrite(length,6);#else // SOCKET_STRINGS  bufferedwrite((char*)&size,sizeof(unsigned int));#endif // SOCKET_STRINGS  // Send the string itself  bufferedwrite(s.data(),size);}string Socket::readuntil(const int length){  string r;#ifdef SOCKET_DEBUG  printf("Socket::readuntil: expecting %d bytes\n",length);  // coherency checks (these are heuristic, they are only useful for  // SOCKET_DEBUG)  assert(length>0 && length<100000);#endif  // Do we have enough data in the current line buffer? If not, we  // need to get some more data from the socket.  while(r.length()<length && !eof){    const int bufsize=1024;    char b[bufsize];    int read;    if(bufsize<length-r.length()) read=Read(b,bufsize);    else read=Read(b,length-r.length());    // Stack it into the buffer    r.append(b,read);  }  if(r.size()>length) throw string("Socket::readuntil: indigestion");  if(eof) throw string("Socket::readuntil: EOF");  return r;}string Socket::readstring(){  string buffer,r;  unsigned int length;  // Find out the length of the next bit#ifdef SOCKET_STRINGS  buffer=readuntil(6);  if(!eof){    // We need to use %u (= unsigned _decimal_ int) because %i would    // think that the first '0' means its an octal number.    sscanf(buffer.substr(0,6).c_str(),"%u",&length);  }#else  Read((char*)&length,sizeof(unsigned int));#endif#ifdef SOCKET_DEBUG  printf("Socket::readstring: have to read %d characters\n",length);#endif  // Get the next bit itself  r=readuntil(length);#ifdef SOCKET_DEBUG  printf("Socket::readstring: read string \"%s\"\n",r.c_str());#endif  return r;}// Explicit template instanciation for special type string (which does// not need converting before going through the socket).template<> Socket &operator<<(Socket &S,const string x){  S.writestring(x);  return S;}template<> Socket &operator>>(Socket &S,string &x){  x=S.readstring();  return S;}// C strings. Just reverts back to the previous case (C++ strings).template<> Socket &operator<<(Socket &S,char* x){  string s=x;  S.writestring(s);  return S;}template<> Socket &operator<<(Socket &S,const char* x){  string s=x;  S.writestring(s);  return S;}// When not in debug mode, try and reduce the amount of data exchanged// to a minimum.#ifdef SOCKET_DEBUG#define CMD_TYPE string#define CMD_PROGRAM "program"#define CMD_COLOR "color"#define CMD_POINT "point"#define CMD_LINE "line"#define CMD_TEXT "text"#define CMD_PEN "pen"#define CMD_POLYGON "polygon"#define CMD_CIRCLE "circle"#define CMD_CLEAR "clear graphics"#define CMD_FLUSH "flush graphics"#define CMD_LINE_WIDTH "query line width"#define CMD_LINE_HEIGHT "query line height"#define CMD_PAUSE "pause"#define CMD_STDOUT "stdout"#define CMD_ERROR "error"#define CMD_RESUME "resume"#define CMD_SERVER_DONE "server done"#else#define CMD_TYPE unsigned char#define CMD_PROGRAM 'a'#define CMD_COLOR 'b'#define CMD_POINT 'c'#define CMD_LINE 'd'#define CMD_TEXT 'e'#define CMD_PEN 'f'#define CMD_POLYGON 'g'#define CMD_CIRCLE 'h'#define CMD_CLEAR 'i'#define CMD_FLUSH 'j'#define CMD_LINE_WIDTH 'k'#define CMD_LINE_HEIGHT 'l'#define CMD_PAUSE 'm'#define CMD_STDOUT 'n'#define CMD_ERROR 'o'#define CMD_RESUME 'p'#define CMD_SERVER_DONE 'q'#endif// Socket through which the server sends all its graphical commands to// the IDE client.#ifdef SERVERSocket *serversocket;#endif// Client-side sockets#ifdef CLIENT// Uses a specific socket to get all connection calls from the// server(s). This strategy allows us to imagine several servers// connecting to one IDE client in the future.Socket *switchboard=NULL;// Socket through which the client receives commands from the server.Socket clientsocket;#endif// Arbitrarily chosen socket communication port, shared between client// and server. todo: the end-user should be able to choose one// depending on his local configuration.Socket::Port commport;#ifdef CLIENT// Opens a new socket to comunicate with the servervoid newswitchboard(){  assert(switchboard==NULL);  // Default TCP port to communicate with the server  commport=34567;  int portshift=0;  // Opening a communication socket to listen to all future server  // connections. When there is a problem, it could very well be due  // to several IDEs running on the same machine for several different  // users, or to a zombie staying in memory after a dirty crash. So  // we need to try several different ports.  bool portok=false;  while(!portok && portshift<20){    try{      switchboard=new Socket(commport+portshift);      portok=true;    }    catch(string explanation){      cerr<<"Problem opening port "<<tostring(commport+portshift)<<": "	  <<explanation<<endl;      portshift++;    }  }  // If we cannot communicate with the server, we can still open the  // IDE to edit FreeFem++ files.  if(portok) commport+=portshift;  else{    switchboard=NULL;    throw string("No TCP port available for server communication");  }#ifndef NDEBUG  cout<<"client: using port "<<tostring(commport)<<" for server communication"      <<endl;#endif}#endif // CLIENT

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?