📄 i_tcp.c
字号:
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: i_tcp.c,v 1.33 2001/02/24 13:35:20 bpereira Exp $//// Copyright (C) 1998-2000 by DooM Legacy Team.//// 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.////// $Log: i_tcp.c,v $// Revision 1.33 2001/02/24 13:35:20 bpereira// no message//// Revision 1.32 2001/02/10 12:27:13 bpereira// no message//// Revision 1.31 2001/01/05 18:17:43 hurdler// fix master server bug//// Revision 1.30 2000/11/26 00:46:31 hurdler// small bug fixes//// Revision 1.29 2000/10/21 08:43:29 bpereira// no message//// Revision 1.28 2000/10/16 20:02:29 bpereira// no message//// Revision 1.27 2000/10/08 13:30:00 bpereira// no message//// Revision 1.26 2000/10/01 15:20:23 hurdler// Add private server//// Revision 1.25 2000/09/28 20:57:15 bpereira// no message//// Revision 1.24 2000/09/15 19:49:22 bpereira// no message//// Revision 1.23 2000/09/10 10:43:21 metzgermeister// *** empty log message ***//// Revision 1.22 2000/09/08 22:28:30 hurdler// merge masterserver_ip/port in one cvar, add -private//// Revision 1.21 2000/09/01 18:23:42 hurdler// fix some issues with latest network code changes//// Revision 1.20 2000/08/31 14:30:55 bpereira// no message//// Revision 1.19 2000/08/29 15:53:47 hurdler// Remove master server connect timeout on LAN (not connected to Internet)//// Revision 1.18 2000/08/21 11:06:44 hurdler// Add ping and some fixes//// Revision 1.17 2000/08/17 23:18:05 hurdler// fix bad port sent to master server when using -udpport//// Revision 1.16 2000/08/16 23:39:41 hurdler// fix a bug with windows sockets//// Revision 1.15 2000/08/16 17:21:50 hurdler// update master server code (bis)//// Revision 1.14 2000/08/16 15:44:18 hurdler// update master server code//// Revision 1.13 2000/08/16 14:10:01 hurdler// add master server code//// Revision 1.12 2000/08/10 14:55:56 ydario// OS/2 port//// Revision 1.11 2000/08/10 14:08:48 hurdler// no message//// Revision 1.10 2000/08/03 17:57:42 bpereira// no message//// Revision 1.9 2000/04/21 13:03:27 hurdler// apply Robert's patch for SOCK_Get error. Boris, can you verify this?//// Revision 1.8 2000/04/21 00:01:45 hurdler// apply Robert's patch for SOCK_Get error. Boris, can you verify this?//// Revision 1.7 2000/04/16 18:38:07 bpereira// no message//// Revision 1.6 2000/03/29 19:39:48 bpereira// no message//// Revision 1.5 2000/03/08 14:44:52 hurdler// fix "select" problem under linux//// Revision 1.4 2000/03/07 03:32:24 hurdler// fix linux compilation//// Revision 1.3 2000/03/06 15:46:43 hurdler// compiler warning removed//// Revision 1.2 2000/02/27 00:42:10 hurdler// fix CR+LF problem//// Revision 1.1.1.1 2000/02/22 20:32:32 hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION:// NOTE: This is not realy Os dependant because all Os have the same Socket api// Just use '#ifdef' for Os dependant stuffs////-----------------------------------------------------------------------------#include <stdlib.h>#include <string.h>#include <stdio.h>#ifdef __OS2__#include <sys/types.h>#include <sys/time.h>#endif // __OS2__#ifdef __WIN32__#include <winsock.h>#include <wsipx.h>#else#if !defined(SCOUW2) && !defined(SCOUW7) && !defined(__OS2__)#include <arpa/inet.h>#endif#include <sys/socket.h>#include <netinet/in.h>#include <unistd.h>#include <netdb.h>#include <sys/ioctl.h>#include <errno.h>#include <time.h>#define STD_STRING_LEN 256 // Just some standard length for a char string#ifdef __DJGPP__#include <lsck/lsck.h>//#define strerror lsck_strerror// ipx not iet supported in libsocket (cut and pasted from wsipx.h (winsock)typedef struct sockaddr_ipx { short sa_family; char sa_netnum[4]; char sa_nodenum[6]; unsigned short sa_socket;} SOCKADDR_IPX, *PSOCKADDR_IPX;#define NSPROTO_IPX 1000#endif // djgpp#ifdef __OS2__// ipx not iet supported in libsocket (cut and pasted from wsipx.h (winsock)#define AF_IPX 23 /* Novell Internet Protocol */typedef struct sockaddr_ipx { short sa_family; char sa_netnum[4]; char sa_nodenum[6]; unsigned short sa_socket;} SOCKADDR_IPX, *PSOCKADDR_IPX;#define NSPROTO_IPX 1000#endif // os2#ifdef LINUX #include <sys/time.h> # ifdef __GLIBC__ #include <netipx/ipx.h> #else #include <linux/ipx.h> #endif // glibc typedef struct sockaddr_ipx SOCKADDR_IPX, *PSOCKADDR_IPX; #define NSPROTO_IPX PF_IPX#endif // linux#endif // win32#include "doomdef.h"#include "i_system.h"#include "i_net.h"#include "d_net.h"#include "m_argv.h"#include "command.h"#include "doomstat.h"#include "mserv.h" //Hurdler: support master server#ifdef __WIN32__ // some undifined under win32 #define IPPORT_USERRESERVED 5000 #define errno h_errno // some very strange things happen when not use h_error ?!? #define EWOULDBLOCK WSAEWOULDBLOCK #define EMSGSIZE WSAEMSGSIZE #define ECONNREFUSED WSAECONNREFUSED#else // linux or djgpp #define SOCKET int #define INVALID_SOCKET -1#endif// win32 or djgpp#if defined( WIN32) || defined( __DJGPP__ ) // winsock stuff (in winsock a socket is not a file) #define ioctl ioctlsocket #define close closesocket#endiftypedef union { struct sockaddr_in ip; struct sockaddr_ipx ipx;} mysockaddr_t;static mysockaddr_t clientaddress[MAXNETNODES+1]; static SOCKET mysocket = -1;static boolean nodeconnected[MAXNETNODES+1];static boolean ipx;int sock_port = (IPPORT_USERRESERVED +0x1d ); // 5029char *SOCK_AddrToStr(mysockaddr_t *sk){ static char s[50]; if( sk->ip.sin_family==AF_INET) { sprintf(s,"%d.%d.%d.%d:%d",((byte *)(&(sk->ip.sin_addr.s_addr)))[0], ((byte *)(&(sk->ip.sin_addr.s_addr)))[1], ((byte *)(&(sk->ip.sin_addr.s_addr)))[2], ((byte *)(&(sk->ip.sin_addr.s_addr)))[3], ntohs(sk->ip.sin_port)); } else#ifdef LINUX if( sk->ipx.sipx_family==AF_IPX ) { sprintf(s,"%08x.%02x%02x%02x%02x%02x%02x:%d", sk->ipx.sipx_network, (byte)sk->ipx.sipx_node[0], (byte)sk->ipx.sipx_node[1], (byte)sk->ipx.sipx_node[2], (byte)sk->ipx.sipx_node[3], (byte)sk->ipx.sipx_node[4], (byte)sk->ipx.sipx_node[5], sk->ipx.sipx_port); }#else if( sk->ipx.sa_family==AF_IPX ) { sprintf(s,"%02x%02x%02x%02x.%02x%02x%02x%02x%02x%02x:%d", (byte)sk->ipx.sa_netnum[0], (byte)sk->ipx.sa_netnum[1], (byte)sk->ipx.sa_netnum[2], (byte)sk->ipx.sa_netnum[3], (byte)sk->ipx.sa_nodenum[0], (byte)sk->ipx.sa_nodenum[1], (byte)sk->ipx.sa_nodenum[2], (byte)sk->ipx.sa_nodenum[3], (byte)sk->ipx.sa_nodenum[4], (byte)sk->ipx.sa_nodenum[5], sk->ipx.sa_socket); }#endif // linux else sprintf(s,"Unknow type"); return s;}boolean IPX_cmpaddr(mysockaddr_t *a,mysockaddr_t *b){#ifdef LINUX return ((memcmp(&(a->ipx.sipx_network) ,&(b->ipx.sipx_network) ,4)==0) && (memcmp(&(a->ipx.sipx_node),&(b->ipx.sipx_node),6)==0));#else return ((memcmp(&(a->ipx.sa_netnum) ,&(b->ipx.sa_netnum) ,4)==0) && (memcmp(&(a->ipx.sa_nodenum),&(b->ipx.sa_nodenum),6)==0));#endif // linux}boolean UDP_cmpaddr(mysockaddr_t *a,mysockaddr_t *b){ return (a->ip.sin_addr.s_addr == b->ip.sin_addr.s_addr && a->ip.sin_port == b->ip.sin_port);}boolean (*SOCK_cmpaddr) (mysockaddr_t *a,mysockaddr_t *b);static int getfreenode( void ){ int j; for(j=0;j<MAXNETNODES;j++) if( !nodeconnected[j] ) { nodeconnected[j]=true; return j; } return -1;}//Hurdler: something is wrong with Robert's patch and win2kvoid SOCK_Get(void){ int i,j,c; size_t fromlen; mysockaddr_t fromaddress; fromlen = sizeof(fromaddress); c = recvfrom (mysocket, (char *)&doomcom->data, MAXPACKETLENGTH, 0, (struct sockaddr *)&fromaddress, &fromlen ); if (c == -1 ) { if ( (errno==EWOULDBLOCK) || (errno==EMSGSIZE) || (errno==ECONNREFUSED) ) { doomcom->remotenode = -1; // no packet return; } I_Error ("SOCK_Get: %s",strerror(errno)); } // DEBFILE(va("Get from %s\n",SOCK_AddrToStr(&fromaddress))); // find remote node number for (i=0 ; i<MAXNETNODES ; i++) if ( SOCK_cmpaddr(&fromaddress,&(clientaddress[i])) ) { doomcom->remotenode = i; // good packet from a game player doomcom->datalength = c; return; } // not found // find a free slot j=getfreenode(); if(j>0) { memcpy(&clientaddress[j],&fromaddress,fromlen);#ifdef DEBUGFILE if( debugfile ) fprintf(debugfile,"New node detected : node:%d address:%s\n",j,SOCK_AddrToStr(&clientaddress[j]));#endif doomcom->remotenode = j; // good packet from a game player doomcom->datalength = c; return; } // node table full if( debugfile ) fprintf(debugfile,"New node detected : No more free slote\n"); doomcom->remotenode = -1; // no packet}fd_set set;// check if we can send (do not go over the buffer)boolean SOCK_CanSend(void){static struct timeval timeval_for_select={0,0}; // huh Boris, are you sure about the 1th argument: // it is the highest-numbered descriptor in any of the three // sets, plus 1 (I suppose mysocket + 1). // BP:ok, no prob since it is ignored in windows :) return select(mysocket + 1,NULL,&set,NULL,&timeval_for_select);}void SOCK_Send(void){ int c; if( !nodeconnected[doomcom->remotenode] ) return; c = sendto (mysocket , (char *)&doomcom->data, doomcom->datalength
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -