📄 nwtcp.c
字号:
strcat(con->nwinfo.ConnInfo,Inet_NtoA(con->tcpinfo.addr.sin_addr)); strcat(con->nwinfo.ConnInfo,":"); sprintf(tbuf,"%03d",ntohs(con->tcpinfo.addr.sin_port)); strcat(con->nwinfo.ConnInfo,tbuf); /* put new connection in the list */ con->prior = NULL; con->next = TCPList; if(con->next != NULL) con->next->prior = con; TCPList = con; return (NWCONN *) con;}/************************************************************************** NAME: TCPClose** SYNOPSIS: int TCPClose(NWCONN *conn);** ** DESCRIPTION: Closes a TCP connection.** RETURNS: 0 --> no error** else error code*************************************************************************/int TCPClose(NWCONN *conn){ TCPCONN *tcon; tcon = (TCPCONN *) conn; /* find and remove the connection in the list */ if(TCPList == NULL) return NW_ERROR+1; if(TCPList == tcon) { TCPList = TCPList->next; if(TCPList!=NULL) TCPList->prior = NULL; } else { tcon->prior->next = tcon->next; tcon->next->prior = tcon->prior; } /* notify NW of close */ TCPCBClose(conn); /* deregister and free */ BlockDeRegister(tcon->tcpinfo.blk); soclose(tcon->tcpinfo.sckt); DnpapFree(tcon->tcpinfo.blk); DnpapFree(tcon->nwinfo.ConnInfo); DnpapFree(tcon); return 0;}/************************************************************************** NAME: TCPSend** SYNOPSIS: int TCPSend(NWCONN *conn,BYTE *frame, int len)** ** DESCRIPTION: Send a frame through the TCP connection.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/int TCPSend(NWCONN *conn,BYTE *frame,int len){ TCPCONN *tcon; int iret; tcon = (TCPCONN *) conn; iret = send(tcon->tcpinfo.sckt,frame,len,0); if(iret < 0 || iret != len) return 1; else return 0;}/************************************************************************** NAME: TCPSetRecCB** SYNOPSIS: void TCPSetRecCB(** NWCONN *conn,** int (*CBReceive)(NWCONN *con,BYTE *frame,int len))** ** DESCRIPTION: Sets the receive callback function a a connection.** should be called for the Open Callback of the application.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/void TCPSetRecCB( NWCONN *conn, int (*CBReceive)(NWCONN *con,BYTE *frame,int len)){ TCPCONN *tcon; tcon = (TCPCONN *) conn; tcon->tcpinfo.CBRec = CBReceive;}/************************************************************************** NAME: TCPGetEntry** SYNOPSIS: char *TCPGetEntry()** DESCRIPTION: Report the connection entry of this layer. Should** be in such a format that other node can use ** this entry to connect to this iface.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/char *TCPGetEntry(void){ return TCPEntry;}/************************************************************************** NAME: TCPConfig** SYNOPSIS: int TCPConfig(char *cfg);** ** DESCRIPTION: Configs a TCP connection.** The TCP library understands the following configuration** options:**** noserver dont start serverport** server do start serverport** serverport=<nr> sets the TCP serverport** ** RETURNS: 0 --> no error** else error code*************************************************************************/int TCPConfig(char *cfg){ char cmd[32]; char *ptr,*arg,*cptr; ptr = cfg; cptr = cmd; while((*ptr != '=') && (*ptr != '\0')) *cptr++ = *ptr++; *cptr='\0'; if(*ptr == '\0') arg=NULL; else arg=ptr+1; /* cmd should now contain the command, arg should point to the argument string */ if(strcmp(cmd,"server") == 0) { /* start server at init time */ TCPDefaultParam.server=1; } else if(strcmp(cmd,"noserver") == 0) { /* do not start server */ TCPDefaultParam.server=0; } else if(strcmp(cmd,"serverport") == 0) { /* set serverport */ if(arg!=NULL) TCPDefaultParam.ServerPort=atoi(arg); } else { /* unknown command */ return NW_ERROR; } return 0;}static int CBTcpServerBlock(BLOCK *blk, int reason,void *param){ if(blk != &ServerBlock) { DnpapMessage(DMC_WARNING,NW_ERROR+7,"wrong server block"); return NW_ERROR+7; } switch(reason) { case BLOCKEVENT_READ: /* on the server socket, this is interpreted as a connection */ /* request, this is handle by a seperate function */ return ConnectRequest(); break; case BLOCKEVENT_WRITE: /* ignore these events */ DnpapMessage(DMC_WARNING,NW_ERROR+30,"BLOCKEVENT_WRITE on serverport"); break; case BLOCKEVENT_EXCEPT: /* ignore these events */ DnpapMessage(DMC_WARNING,NW_ERROR+30,"BLOCKEVENT_EXCEPTon serverport"); break; default: DnpapMessage(DMC_WARNING,NW_ERROR+8,"unknown block event"); return NW_ERROR+8; break; } return 0;}static BYTE RecBuf[10000];static int CBTcpSocketBlock(BLOCK *blk, int reason, void *param){ TCPCONN *tconn; int nrrec; /* remember, param contains a pointer to a TCPCONN */ tconn = param; switch(reason) { case BLOCKEVENT_READ: /* a read of length 0 is interpreted as a close */ nrrec = read(tconn->tcpinfo.sckt,RecBuf,10000); if(nrrec < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+42,"read error"); return NW_ERROR+42; } if(nrrec == 0) { /* this is interpreted as a close of the socket */ return TCPClose((NWCONN *) tconn); } /* notify NW of the receiped */ if(tconn->tcpinfo.CBRec != NULL) return (tconn->tcpinfo.CBRec)((NWCONN *) tconn,RecBuf,nrrec); break; case BLOCKEVENT_WRITE: break; case BLOCKEVENT_EXCEPT: DnpapMessage(DMC_WARNING,NW_ERROR+30,"EXEPTEVENT_WRITE on normalport"); break; default: DnpapMessage(DMC_WARNING,NW_ERROR+8,"unknown block event"); return NW_ERROR+8; break; } return 0;}static int ConnectRequest(void){ int nsckt,iret; char tbuf[8]; TCPCONN *tcon; BLOCK *blk; int ts; /* someone has requested a connection */ /* allocate a connection and block structure */ if((tcon = DnpapMalloc(sizeof(TCPCONN))) == NULL ) { DnpapMessage(DMC_WARNING,NW_ERROR+40,"alloc failed"); return NW_ERROR+40; } if((blk = DnpapMalloc(sizeof(BLOCK))) == NULL ) { DnpapFree(tcon); DnpapMessage(DMC_WARNING,NW_ERROR+40,"alloc failed"); return NW_ERROR+40; } /* nsckt will become a new socket, fully resolved, the original ServerSocket will stay open for future connection requests */ ts = sizeof(tcon->tcpinfo.addr); nsckt = accept( ServerSocket, (struct sockaddr *)&(tcon->tcpinfo.addr), &ts); /* read message-discard mode */ if(nsckt < 0) { DnpapFree(blk); DnpapFree(tcon); DnpapMessage(DMC_WARNING,NW_ERROR+41,"accept failed"); return NW_ERROR+41; } ioctl(nsckt,I_SRDOPT,(caddr_t)RMSGD); /* termine a correct connection string */ tcon->nwinfo.ConnInfo = DnpapMalloc(32); strcpy(tcon->nwinfo.ConnInfo,"tcp:"); strcat(tcon->nwinfo.ConnInfo,Inet_NtoA(tcon->tcpinfo.addr.sin_addr)); strcat(tcon->nwinfo.ConnInfo,":"); sprintf(tbuf,"%03d",ntohs(tcon->tcpinfo.addr.sin_port)); strcat(tcon->nwinfo.ConnInfo,tbuf); tcon->tcpinfo.sckt = nsckt; tcon->tcpinfo.blk = blk; tcon->tcpinfo.conPort = 0; tcon->tcpinfo.CBRec = NULL; /* should be set by NW layer */ /* inform NW layer of creation */ TCPCBOpen((NWCONN *)tcon,tcon->nwinfo.ConnInfo); /* after this, the read-callback should be known, and the block can be attached */ blk->sckt = nsckt; if((iret = BlockRegister(blk,tcon,CBTcpSocketBlock)) != 0) { DnpapFree(blk); DnpapFree(tcon->nwinfo.ConnInfo); DnpapFree(tcon); DnpapMessage(DMC_WARNING,NW_ERROR+31,"could not register block!"); return NW_ERROR+31; } /* connect the new connection to the connection list */ tcon->next = TCPList; tcon->prior = NULL; TCPList->prior = tcon; TCPList = tcon; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -