⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csocket.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		mythis->iStatus=-2;		GB.Ref (mythis);		CSocket_post_error(mythis);		return 2;	}  	mythis->iPort=myport;	mythis->conn_type=0;	/******************************************	Let's turn hostname into host IP	*******************************************/	if (!mythis->DnsTool)	{		GB.New((void**)&mythis->DnsTool,GB.FindClass("DnsClient"),NULL,NULL);		mythis->DnsTool->CliParent=(void*)mythis;	}  	if (mythis->DnsTool->iStatus > 0 ) dns_close_all(mythis->DnsTool);  	dns_set_async_mode(1,mythis->DnsTool);  	GB.FreeString (&(mythis->DnsTool->sHostName));  	GB.NewString(&mythis->DnsTool->sHostName,sHost,lenhost);  	mythis->DnsTool->finished_callback=CSocket_CallBackFromDns;	/********************************************	We start DNS lookup, when it is finished	it will call to CSocket_CallBack_fromDns,	and we'll continue there connection proccess	********************************************/	mythis->iStatus=5; /* looking for IP */	dns_thread_getip(mythis->DnsTool);	mythis->stream.desc=&SocketStream;	mythis->stream._free[0]=(long)mythis;  	mythis->iUsePort=mythis->iPort;                        // $BM        if (mythis->Host) GB.FreeString(&mythis->Host);        if (mythis->Path) GB.FreeString(&mythis->Path);		GB.NewString(&mythis->Host,sHost,0);	return 0;}/**********************************************This function is used to peek data from socket,you have to pass 3 parameters:mythis -> CSocket objectbuf    -> Data Buffer (you have to free it after using it!)MaxLen -> 0 no limit, >0 max. data t read***********************************************/int CSocket_peek_data(CSOCKET *mythis,char **buf,int MaxLen){  int retval=0;  int NoBlock=0;  int nread=0;  int bytes=0;  (*buf)=NULL;  nread=ioctl(mythis->Socket,FIONREAD,&bytes); /* Is there anythig to read? */  if (nread)  	retval=-1;  else  	retval=0;  if ( (!retval) && (bytes) ) /* if there's anything to receive */  {  	if (bytes > MAX_CLIENT_BUFFER_SIZE) bytes=MAX_CLIENT_BUFFER_SIZE;	if (MaxLen >0 ) bytes=MaxLen;	GB.Alloc((void**)buf,bytes);	(*buf)[0]='\0';  	ioctl(mythis->Socket,FIONBIO,&NoBlock);	USE_MSG_NOSIGNAL(retval=recv(mythis->Socket,(void*)(*buf),bytes*sizeof(char),MSG_PEEK|MSG_NOSIGNAL));	NoBlock++;  	ioctl(mythis->Socket,FIONBIO,&NoBlock);  }  if (retval==-1)  {  	/* An error happened while trying to receive data : SOCKET ERROR */	if (*buf)	{		GB.Free((void**)buf);		buf=NULL;	}	GB.Watch (mythis->Socket , GB_WATCH_NONE , (void *)CSocket_CallBack,0);	mythis->stream.desc=NULL;	close(mythis->Socket);	mythis->iStatus=-4;	GB.Ref (mythis);	CSocket_post_error(mythis);	return -1;  }  return retval;}/*****************************************************************************************##########################################################################################-------------------------SOCKET GAMBAS INTERFACE IMPLEMENTATION---------------------##########################################################################################******************************************************************************************//********************************************************************Returns current Status of the socket (connected,connecting,closed)*********************************************************************/BEGIN_PROPERTY ( CSOCKET_Status )  GB.ReturnInteger(THIS->iStatus);END_PROPERTY/******************************************************************** Port to connect to. Can be 'Net.Local' for Unix sockets, or  1-65535 for TCP sockets ********************************************************************/BEGIN_PROPERTY(CSOCKET_Port)	if (READ_PROPERTY)	{		GB.ReturnInteger(THIS->iUsePort);		return;	}		if (THIS->iStatus>0)	{		GB.Error("Port property can not be changed while working");		return;	}	if (VPROP(GB_INTEGER)<0)	{ THIS->iUsePort=0; return; }	if (VPROP(GB_INTEGER)>65535) 	{ THIS->iUsePort=65535; return; }	THIS->iUsePort=VPROP(GB_INTEGER);END_PROPERTY/*********************************************************************	Host or Path to connect to. If 'Port' value is zero, this	will be a local path, else, a remote host name**********************************************************************/// $BMBEGIN_PROPERTY (CSOCKET_Host)	if (READ_PROPERTY)	{		GB.ReturnNewString(THIS->Host,0);		return;	}	GB.StoreString(PROP(GB_STRING), &THIS->Host);END_PROPERTYBEGIN_PROPERTY (CSOCKET_Path)	if (READ_PROPERTY)	{		GB.ReturnNewString(THIS->Path,0);		return;	}	GB.StoreString(PROP(GB_STRING), &THIS->Path);END_PROPERTY/******************************************************************** Returns current TCP remote port (only when connected via TCP) *********************************************************************/BEGIN_PROPERTY ( CSOCKET_RemotePort )	if ( THIS->iStatus != 7   )   { GB.ReturnInteger(0); return; }	if ( THIS->conn_type != 0 )   { GB.ReturnInteger(0); return; }	GB.ReturnInteger(THIS->iPort);END_PROPERTY/******************************************************************** Returns current TCP local port (only when connected via TCP) *********************************************************************/BEGIN_PROPERTY ( CSOCKET_LocalPort )	if ( THIS->iStatus != 7   )   { GB.ReturnInteger(0); return; }	if ( THIS->conn_type != 0 )   { GB.ReturnInteger(0); return; }	GB.ReturnInteger(THIS->iLocalPort);END_PROPERTY/*********************************************************************** Returns current foreing host IP (only when connected via TCP) ***********************************************************************/BEGIN_PROPERTY ( CSOCKET_RemoteHost )  if ( THIS->iStatus==7 && (THIS->conn_type==0) )  {  	GB.ReturnString(THIS->sRemoteHostIP);  	return;  }  GB.ReturnString(NULL);END_PROPERTY/*********************************************************************** Returns current local host IP (only when connected via TCP) ***********************************************************************/BEGIN_PROPERTY ( CSOCKET_LocalHost )  if ( THIS->iStatus==7 && (THIS->conn_type==0) )  {  	GB.ReturnString(THIS->sLocalHostIP);	return;  }  GB.ReturnString(NULL);END_PROPERTY// $BM#if 0/*********************************************************************** Returns current Path (only when connected via UNIX socket) ***********************************************************************/BEGIN_PROPERTY ( CSOCKET_Path )	int mylen;	char numtmp[6];	char *strtmp;	if ( (THIS->iStatus==7) && (THIS->conn_type==1)  )	{		GB.ReturnString(THIS->sPath);		return;	}	if ( (THIS->iStatus==7) && (THIS->conn_type==0)  )	{		snprintf(numtmp,6,"%d",THIS->iPort);		mylen=strlen(THIS->sRemoteHostIP);		mylen++;		mylen+=strlen(numtmp);		mylen++;		GB.Alloc((void**)&strtmp,sizeof(char)*mylen);		strcpy(strtmp,THIS->sRemoteHostIP);		strcat(strtmp,":");		strcat(strtmp,numtmp);		GB.ReturnNewString(strtmp,0);		GB.Free((void**)&strtmp);		return;	}	GB.ReturnString(NULL);END_PROPERTY#endif/**************************************************** Gambas object "Constructor" ****************************************************///BEGIN_METHOD(CSOCKET_new,GB_STRING sPath;)BEGIN_METHOD_VOID(CSOCKET_new)  //char *buf=NULL;  //int retval;  //int nport=0;    // $BM - The object is filled with zero at creation  //THIS->stream.desc=NULL;  //THIS->c_parent=NULL;  //THIS->DnsTool=NULL;  //THIS->conn_type=0;  //THIS->iStatus=0;  THIS->iUsePort=80;  //THIS->sLocalHostIP=NULL;  //THIS->sRemoteHostIP=NULL;  //THIS->HostOrPath=NULL;  //THIS->OnClose=NULL;  /*  if (MISSING (sPath) ) return;  if (!STRING (sPath) ) return;  retval=IsHostPath(STRING(sPath),&buf,&nport);  if (!retval)  {  	GB.Error("Invalid Host / Path string");	return;  }  if (retval==2)  {  	switch(CSocket_connect_unix(THIS,STRING(sPath),LENGTH(sPath)))  	{  		case 1: GB.Error("Socket is already connected. Close it first."); return;		case 2: GB.Error("Invalid Path length"); return;  	}  	return;  }  if (retval==1)  {  	if (!buf)	{		GB.Error("Invalid host name");		return;	}	if (nport < 1)	{		GB.Error("Invalid Port");		return;	}	retval=CSocket_connect_socket(THIS,buf,strlen(buf),nport );	GB.Free((void**)&buf);	switch(retval)	{  		case 1: GB.Error("Socket is already connected. Close it first."); return;		case 8: GB.Error("Port value out of range."); return;		case 9: GB.Error("Invalid Host Name."); return;  	}  	return;  }  */END_METHOD/************************************************** Gambas object "Destructor" **************************************************/BEGIN_METHOD_VOID(CSOCKET_free)   if (THIS->DnsTool)  {	dns_close_all(THIS->DnsTool);	GB.Unref((void**)&THIS->DnsTool);	THIS->DnsTool=NULL;  }  if (THIS->iStatus>0)  {  	GB.Watch (THIS->Socket , GB_WATCH_NONE , (void *)CSocket_CallBack,0);	THIS->stream.desc=NULL;	close(THIS->Socket);	if (THIS->OnClose) THIS->OnClose((void*)THIS);  	THIS->iStatus=0;  }  GB.FreeString(&THIS->sPath);  GB.FreeString(&THIS->sLocalHostIP);  GB.FreeString(&THIS->sRemoteHostIP);  // $BM  GB.FreeString(&THIS->Host);  GB.FreeString(&THIS->Path);END_METHODBEGIN_METHOD_VOID(CSOCKET_exit) END_METHOD/************************************************************* To Peek data arrived from the other side of the socket **************************************************************/BEGIN_METHOD_VOID(CSOCKET_Peek)  char *buf=NULL;  int retval=0;  if (THIS->iStatus != 7) /* if socket is not connected we can't receive anything */  {      GB.Error("Socket is not active. Connect it first.");      return;  }  retval=CSocket_peek_data(THIS,&buf,0);  if (retval==-1)  {  	/* An error happened while trying to receive data : SOCKET ERROR */	if (buf) GB.Free((void**)&buf);	GB.ReturnNewString(NULL,0);	return;  }  if ( retval>0)  	GB.ReturnNewString (buf,retval);  else  	GB.ReturnNewString (NULL,0);  if (buf) GB.Free((void**)&buf);END_METHOD/************************************************************************** To start a TCP or UNIX connection **************************************************************************/ // $BM BEGIN_METHOD(CSOCKET_Connect,GB_STRING HostOrPath;GB_INTEGER Port;)  int port;  int err;  port = VARGOPT(Port, THIS->iUsePort);  if (!port)  {    if (MISSING(HostOrPath))      err = CSocket_connect_unix(THIS,THIS->Path,GB.StringLength(THIS->Path));    else      err = CSocket_connect_unix(THIS,STRING(HostOrPath),LENGTH(HostOrPath));  }  else  {    if (MISSING(HostOrPath))      err = CSocket_connect_socket(THIS,THIS->Host,GB.StringLength(THIS->Host),port);    else      err = CSocket_connect_socket(THIS,STRING(HostOrPath),LENGTH(HostOrPath),port);  }    switch (err)  {    case 1: GB.Error("Socket is already connected. Close it first."); return;    case 2: GB.Error("Invalid Path length"); return;    case 8: GB.Error("Port value out of range."); return;    case 9: GB.Error("Invalid Host Name."); return;  }END_METHOD/********************************************************** Here we declare public structure of Socket Class ***********************************************************/GB_DESC CSocketDesc[] ={  GB_DECLARE("Socket", sizeof(CSOCKET)),  GB_INHERITS(".Stream"),  GB_EVENT("Error", NULL, NULL, &SocketError),  GB_EVENT("Read", NULL, NULL, &Socket_Read),  GB_EVENT("Ready", NULL, NULL, &Connected),  GB_EVENT("Closed", NULL, NULL, &Closed),  GB_EVENT("Found", NULL, NULL, &HostFound),  GB_STATIC_METHOD ( "_exit" , NULL , CSOCKET_exit , NULL ),  //GB_METHOD("_new", NULL, CSOCKET_new, "[(Path)s]"),  GB_METHOD("_new", NULL, CSOCKET_new, NULL),  GB_METHOD("_free", NULL, CSOCKET_free, NULL),  GB_METHOD("Peek", "s", CSOCKET_Peek, NULL),  GB_METHOD("Connect",NULL, CSOCKET_Connect,"[(HostOrPath)s(Port)i]"),  GB_PROPERTY_READ("Status", "i", CSOCKET_Status),  GB_PROPERTY_READ("RemotePort", "i", CSOCKET_RemotePort),  GB_PROPERTY_READ("LocalPort", "i", CSOCKET_LocalPort),  GB_PROPERTY_READ("RemoteHost", "s", CSOCKET_RemoteHost),  GB_PROPERTY_READ("LocalHost","s",CSOCKET_LocalHost),    GB_PROPERTY("Host","s",CSOCKET_Host),  GB_PROPERTY("Path","s",CSOCKET_Path),  GB_PROPERTY("Port","i",CSOCKET_Port),    GB_CONSTANT("_Properties", "s", "Host,Path,Port=80"),  GB_CONSTANT("_DefaultEvent", "s", "Read"),  GB_END_DECLARE};

⌨️ 快捷键说明

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