//+------------------------------------------------------------------+ //| SocketIsWritable.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com #property version "1.00" #property description "예제가 작동할 수 있도록 터미널 설정에서 허용된 주소 목록에 추가하세요" #property script_show_inputs input string Address ="www.mql5.com"; input int Port =80; bool ExtTLS =false; //+------------------------------------------------------------------+ //| 스크립트 프로그램 시작 함수 | //+------------------------------------------------------------------+ void OnStart(void) { //--- 소켓을 생성하고 핸들을 수신 int socket=SocketCreate(); //--- 핸들을 확인하세요 if(socket!=INVALID_HANDLE) { //--- 모든게 준비되면 연결하세요 if(SocketConnect(socket,Address,Port,1000)) { PrintFormat("Established connection to %s:%d",Address,Port); string subject,issuer,serial,thumbprint; datetime expiration; //--- 연결이 인증서로 보호되는 경우 해당 데이터를 표시합니다 if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration)) { Print("TLS certificate:"); Print(" Owner: ",subject); Print(" Issuer: ",issuer); Print(" Number: ",serial); Print(" Print: ",thumbprint); Print(" Expiration: ",expiration); ExtTLS=true; } //--- GET 요청을 서버에 보내세요 if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\nUser-Agent: MT5\r\n\r\n")) { Print("GET request sent"); //--- 회신 읽기 if(!HTTPRecv(socket,1000)) Print("Failed to get a response, error ",GetLastError()); } else Print("Failed to send GET request, error ",GetLastError()); } else { PrintFormat("Connection to %s:%d failed, error %d",Address,Port,GetLastError()); } //--- 현재 시점에 소켓에 데이터를 쓰는 기능을 저널에 표시 if(SocketIsWritable(socket)) Print("At the current moment in time, writing data to the socket is possible"); else Print("It is not possible to write data to the socket at the current time"); //--- 사용 후 소켓 종료 if(SocketClose(socket)) Print("Now the socket is closed"); } else Print("Failed to create a socket, error ",GetLastError()); /* 결과: At the current moment in time, writing data to the socket is possible Socket is closed now */ } //+------------------------------------------------------------------+ //| 서버에 명열을 보냅니다 | //+------------------------------------------------------------------+ bool HTTPSend(int socket,string request) { //--- 문자열을 문자 배열로 변환하고 종료 0을 버립니다. char req[]; int len=StringToCharArray(request,req)-1; if(len<0) return(false); //--- 포트 443을 통한 보안 TLS 연결이 사용되는 경우 if(ExtTLS) return(SocketTlsSend(socket,req,len)==len); //--- 일반 TCP 연결을 사용하는 경우 return(SocketSend(socket,req,len)==len); } //+------------------------------------------------------------------+ //| 서버 회신 읽기 | //+------------------------------------------------------------------+ bool HTTPRecv(int socket,uint timeout_ms) { char rsp[]; string result; ulong timeout_check=GetTickCount64()+timeout_ms; //--- 데이터가 있는 동안 소켓에서 데이터를 읽습니다. 그러나 시간 초과보다 길지 않도록 합니다. do { uint len=SocketIsReadable(socket); if(len) { int rsp_len; //--- 연결이 안전한지 여부에 따라 다른 읽기 명령 if(ExtTLS) rsp_len=SocketTlsRead(socket,rsp,len); else rsp_len=SocketRead(socket,rsp,len,timeout_ms); //--- 응답 구문 분석 if(rsp_len>0) { result+=CharArrayToString(rsp,0,rsp_len); //--- 응답 헤더만 표시 int header_end=StringFind(result,"\r\n\r\n"); if(header_end>0) { Print("HTTP answer header received:"); Print(StringSubstr(result,0,header_end)); return(true); } //--- 읽기 제한 시간 만료 시간 업데이트 timeout_check=GetTickCount64()+timeout_ms; } } } while(GetTickCount64()<timeout_check && !IsStopped()); return(false); } |