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

📄 tcpipmex.c

📁 A very small 250-line library (written entirely in MATLAB) that allows multiple MATLAB programs to t
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************  MEX file for tcpip toolbox version Candidate 1.2 2000-04-14  for MATLAB 5.x  Copyrigtht (C) Peter Rydes鋞er 1998 - 2000, Mitth鰃skolan, SWEDEN   This program is free software; you can redistribute it and/or  modify it under the terms of the GNU General Public License  as published by the Free Software Foundation; either version 2  of the License, or (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  Notes for Unix implementation  Compile this with:  mex -O tcpipmex.c  Notes for Windows implementation  Compile this with:  mex -O tcpipmex.c ws2_32.lib -DWIN32  Please, send us an e-mail if you use this and/or improve it.  Peter Rydes鋞er                     Mario Bergeron  Mitth鰃skolan                      LYR Signal Processing  謘tersund, Sweden                  Qu閎ec, Canada  e-mail: Peter.Rydesater@ite.mh.se  e-mail: Mario.Bergeron@lyre.qc.ca**********************************************************//******* GENERAL DEFINES *********/#include <stdio.h>#include <stdlib.h>#include <string.h>/******* WINDOWS ONLY DEFINES *********/#ifdef WIN32//#include <windows.h>#include <winsock2.h>#define close(s) closesocket(s)#define nonblockingsocket(s) {  unsigned long ctl = 1;  ioctlsocket( s, FIONBIO, &ctl ); }#define s_errno WSAGetLastError()#define EWOULDBLOCK WSAEWOULDBLOCK#define usleep(a) Sleep(a)/******* NON WINDOWS DEFINES *********/#else#include <errno.h>#define s_errno errno // ?? Is this OK ??#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <unistd.h>#include <fcntl.h>#define nonblockingsocket(s) fcntl(s,F_SETFL,O_NONBLOCK)#include <signal.h>#endif/* DEFINE SIGPIPE and SIG_DFL if its not defined */#ifndef WIN32#ifndef SIGPIPE#define SIGPIPE 13#endif#ifndef SIG_DFL#define SIG_DFL (void(*)())0#endif#ifndef INADDR_NONE#define INADDR_NONE (-1)#endif #endif/* Include header file for matlab mex file functionality */#include "mex.h" /********** DEFINES reletad to tcpipmex own functionality *****************/ /*   Set debuging on/off   */#define debug_view_ipi_status(X)   __debug_view_ipi_status(X)#define MAX_IPI         100       /* Maximum number of simultanius tcpip connections.*/#define NAMEBUFF_LEN    100#define MINBUFFSIZE     1000      /* readbuffer will shrink to this size if datalength                                     is smaller. */#define CBNAMELEN       30#define IPI_FREE         -1       /* Find a new free struct in struct array */#define IPI_CURRENT      -2       /* DO NOT USE! No longer valid .... */#define TCPIP_BACKLOG    10       /* How many pending connections queue will hold *//* Different status of a ipi_info struct handles a file descriptor    */#define STATUS_FREE       -1 #define STATUS_NOCONNECT   0#define STATUS_SERVSOCKET  1#define STATUS_CLIENT      10#define STATUS_SERVER      12/* Structure that hold all information about a tcpip connection. */struct ip_info{    int fid;    double writetimeout;    double readtimeout;    struct sockaddr_in remote_addr;    struct hostent *he;    int status;       /* STATUS_... FREE, NOCONNECT, SERVER, CLIENT ... */    char *buff;       /* Pointer to buffert. */    int bufflen;      /* Length of buffert. */    int buffdatalen;  /* Length used of buffer for data storage.*/    char callback[CBNAMELEN+1];};/* Global list with static length of connections structures holding info about current connection */struct ip_info ipi[MAX_IPI];/* Some global variables that holds values from one to an another matlab call to the tcpipmex */int ipi_index=0;                   /* Current index possition for list of handlers */ unsigned long mex_call_counter=0;  /* Counter that counts how many calls that have been done to tcpipmex */int ret_args=0;                    /* Global variable that holds number of matlab return argumens returned */void *matlab_signal_handler;       /* Holds matlabs default signal handler... *//* Declaration of all sub functions */int move_ipi(int idx);void my_mexReturnValue(int nlhs,mxArray *plhs[],double val);void my_mexReturnString(int nlhs,mxArray *plhs[],const char *str);void my_mexReturnCharArray(int nlhs, mxArray *plhs[], const char *buff,int bufflen);void CopymxCharArray2Buff(const mxArray *array,char *buff,int bufflen);void CleanUpMex(void);int closeall(void);int tcpipserv(int port);void init_ipi(int fid,int server);void close_ipi();void read2buff(int len);void removefrombuff(int len);void *myrealloc(void *ptr,int newsize);void get_sigpipe_handler(int sig);void get_sigpipe_on(void);void get_sigpipe_off(void);int writedata(char*,int);int tcpipsocket(int port);int tcpiplisten(int sockfid);int tcpipserver(int);void __debug_view_ipi_status(char *msg);/* Declaration of implemetation of perror for windows */#ifdef WIN32void perror( char *context );#endif/*****************************************************************//*                                                               *//*    ----Main function that is called from matlab--------       *//*                                                               */void mexFunction(    int           nlhs,           /* number of expected outputs */    mxArray       *plhs[],        /* array of pointers to output arguments */    int           nrhs,           /* number of inputs */    const mxArray *prhs[]         /* array of pointers to input arguments */){  int fun;  struct in_addr addr;  /* Initialization on first call to the mex file */  if(mex_call_counter==0)  {//      int i;#ifdef WIN32      {	  WORD wVersionRequested;	  WSADATA wsaData;	  int wsa_err;	  	  wVersionRequested = MAKEWORD( 2, 0 );	  wsa_err = WSAStartup( wVersionRequested, &wsaData );	  if ( wsa_err )	  {	      mexErrMsgTxt("Error starting WINSOCK32.");	      return;	  }      }#endif      mexAtExit(CleanUpMex);      /* Init all to free */      for(ipi_index=0;ipi_index<MAX_IPI;ipi_index++)	  init_ipi(-1,STATUS_FREE);      ipi_index=0;  }  mex_call_counter++;  ret_args=0;  debug_view_ipi_status("ENTER_MEX");  if(nrhs<2)       mexErrMsgTxt("You must specify at least two arguments!");  if(mxGetM(prhs[0])*mxGetN(prhs[0])!=1)      mexErrMsgTxt("Error on first argument! should be a function selection number.");  fun=(int)mxGetScalar(prhs[0]);  /* ---CLOSE ALL----  */  if(fun<0)  {    closeall();    return;  }  /* Find given handel */  {      int idx;      if(mxGetM(prhs[1])*mxGetN(prhs[1])!=1)	  mexErrMsgTxt("Error on second argument. Specify handler as scalar!");      idx=(int)mxGetScalar(prhs[1]);      if(move_ipi(idx)==0)	  mexErrMsgTxt("Unknown handler!");  }  debug_view_ipi_status("IPI_MOVED!!");    switch(fun)  {/* ---CLOSE--- */  case 0:      {   	  if(ipi[ipi_index].fid<0)   /* Already closed?? */	      mexPrintf("Cant close already closed fid.\n");	  else	      close_ipi();	  break;      }/* ---OPEN AS CLIENT--- */  case 1:      {	char hostname[NAMEBUFF_LEN+1];	int len;	int port;   debug_view_ipi_status("O1");	if(ipi[ipi_index].fid>=0)	  mexErrMsgTxt("This handler is already open !!??");   debug_view_ipi_status("O2");	if(nrhs<3)	    mexErrMsgTxt("Wrong number of arguments for OPEN!");	if(mxIsChar(prhs[2])==0 || mxIsNumeric(prhs[3])==0)	    mexErrMsgTxt("Wrong argument datatype for OPEN!");	len=mxGetM(prhs[2])*mxGetN(prhs[2])+1;	if(len>=NAMEBUFF_LEN)	    mexErrMsgTxt("To long hostname!");	mxGetString(prhs[2], hostname, len);	port=(int)mxGetScalar(prhs[3]);   debug_view_ipi_status("O3");//	ipi[ipi_index].he=gethostbyname(hostname);   debug_view_ipi_status("O4");	if(ipi[ipi_index].he!=NULL)	    addr = *((struct in_addr *)ipi[ipi_index].he->h_addr);	else	{	    /* Can't lookup hostname, try IP address */	    addr.s_addr=inet_addr(hostname);	    if (addr.s_addr==INADDR_NONE)	    {		my_mexReturnValue(nlhs,plhs,-1);			break;	    }	}   debug_view_ipi_status("O5");	ipi[ipi_index].fid=socket(AF_INET, SOCK_STREAM, 0);   debug_view_ipi_status("O5");	if(ipi[ipi_index].fid== IPI_FREE)	{	    /* Can't make socket for connnection to remote host. */	    my_mexReturnValue(nlhs,plhs,-1);	    break;	}   debug_view_ipi_status("O6");	ipi[ipi_index].remote_addr.sin_family=AF_INET;	ipi[ipi_index].remote_addr.sin_port=htons(port);	ipi[ipi_index].remote_addr.sin_addr=addr;	ipi[ipi_index].remote_addr.sin_family=AF_INET;	memset(&ipi[ipi_index].remote_addr.sin_zero, 0,8);	if(connect(ipi[ipi_index].fid,(struct sockaddr *)&ipi[ipi_index].remote_addr,		   sizeof(struct sockaddr)) == -1)	{	    /*Can't connect to remote host. */	    my_mexReturnValue(nlhs,plhs,-1);	    close_ipi();	    break;	}   debug_view_ipi_status("O7");	init_ipi(ipi[ipi_index].fid,STATUS_CLIENT);	nonblockingsocket(ipi[ipi_index].fid); /* Non blocking read! */   debug_view_ipi_status("O8");	my_mexReturnValue(nlhs,plhs,ipi_index);	break;      }/* ---- WRITESTRING ---- */  case 2:      {	int retval=100000;	int sentlen=0;	char *buff;	int len;		if(nrhs<3)	  mexErrMsgTxt("You must specify string to write as third argument!");	if(mxIsChar(prhs[2])==0)	  mexErrMsgTxt("Write string must be array of chars!");	len=mxGetM(prhs[2])*mxGetN(prhs[2]);	if(len==0)	{          my_mexReturnValue(nlhs,plhs,0);	  break;	}	if((buff=(char *)mxMalloc(len))==NULL)	  mexErrMsgTxt("Running out of memory! Can't send string!");	CopymxCharArray2Buff(prhs[2],buff,len);	sentlen=writedata(buff,len);	my_mexReturnValue(nlhs,plhs,sentlen);	mxFree(buff);	break;      }      break;/* ---- READSTRING ---- */  case 3:      {	  int readlen;	  if(nrhs<3)	      mexErrMsgTxt("You must specify maximum of characteer to read!");	  readlen=(int)mxGetScalar(prhs[2]);	  read2buff(readlen);	  if(readlen>ipi[ipi_index].buffdatalen)	      readlen=ipi[ipi_index].buffdatalen;	  my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,readlen);	  removefrombuff(readlen);      }      break;/* ---- READSTRING UNTIL (READLINE) ---- */  case 4:      {	int i;	int readlen;	int flag=0;	int termchar1=13;  /* Two default string termination characters */	int termchar2=10;	if(nrhs<3)	  mexErrMsgTxt("You must specify maximum of characters to read!");	if(nrhs>3) 	  termchar1=termchar2=(int)mxGetScalar(prhs[3]);	if(nrhs>4) 	  termchar2=(int)mxGetScalar(prhs[4]);	readlen=(int)mxGetScalar(prhs[2]);	read2buff(readlen);	for(i=0; i<readlen, i<ipi[ipi_index].buffdatalen; i++)	{	    if(ipi[ipi_index].buff[i]==termchar1 || ipi[ipi_index].buff[i]==termchar2)	    {	      my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,i+1);	      removefrombuff(i+1);	      break;	    }	}	if(readlen==ipi[ipi_index].buffdatalen)                 /*Is read buffer full? */	{	  /* then wrap line...*/	  my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,ipi[ipi_index].buffdatalen);	  removefrombuff(ipi[ipi_index].buffdatalen);         }	else	  /* else return empty*/ 	  my_mexReturnCharArray(nlhs,plhs,"",0);             }      break;/* ----- "VIEW" INCOMMING DATA, (NOT DELETE FROM BUFFER)------ */  case 5:      {	  int readlen;	  readlen=(int)mxGetScalar(prhs[2]);	  read2buff(readlen);	  if(readlen>ipi[ipi_index].buffdatalen)	      readlen=ipi[ipi_index].buffdatalen;	  my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,readlen);      }      break;/* --- RETURN STATUS --- */  case 6:      my_mexReturnValue(nlhs,plhs,ipi[ipi_index].status);      break;/* --- SET_CALLBACK_FUNCTION --- */  case 7:      {	if(nrhs<3)	  mexErrMsgTxt("You must specify a string as callback function name!");	if(mxIsChar(prhs[2])==0)	  mexErrMsgTxt("You must specify a string as callback function name!");	mxGetString(prhs[2],ipi[ipi_index].callback, CBNAMELEN);	break;      }      break;/* --- EXECUTE_CALLBACK_FUNCTION --- */  case 9:      {	  /*.............	    Type a lote here	    ................*/      }      break;/* ---- OPEN_AS_SERVER  ----*/          /* OLD!!! Remove this ???? */   case 10:      {	  int port;	  int idx;	  if(ipi[ipi_index].fid>=0) 	      mexErrMsgTxt("already open??? Always specify handler -1 when open a new!");	  if(nrhs<3)	      mexErrMsgTxt("Wrong number of arguments for OPEN_AS_SERVER!");	  port=(int)mxGetScalar(prhs[2]);	  idx=tcpipserver(port);	  my_mexReturnValue(nlhs,plhs,idx);      }      break;/* ---- OPEN_SERVER_SOCKET ---*/  case 20:     {	 int fd;   /* File descriptor for socket! */	 int port;	 if(ipi[ipi_index].status!=STATUS_NOCONNECT) 	     mexErrMsgTxt("already open??? Always specify handler -1 when open a new!");	 if(nrhs<3)	     mexErrMsgTxt("Wrong number of arguments. specify port number.");	 port=(int)mxGetScalar(prhs[2]);	 fd=tcpipsocket(port);	 if(fd>=0)	 {	     init_ipi(fd,STATUS_SERVSOCKET);  	     my_mexReturnValue(nlhs,plhs,ipi_index);	 }	 else	 {	     init_ipi(-1,STATUS_FREE);  	     my_mexReturnValue(nlhs,plhs,-1);	 }     }     break;     /* ---- OPEN_CONNECTED TO SERVER ---   Listen for calls and return */  case 21:     {	 int conn_fd;//	 int sockfd;	 if(ipi[ipi_index].status!=STATUS_SERVSOCKET)	     mexErrMsgTxt("Its not a open socket you tries listens to...");	 conn_fd=tcpiplisten(ipi[ipi_index].fid);	 if( conn_fd >=0)	 {             /* Find a new free ipi struct for the new connection.... */

⌨️ 快捷键说明

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