📄 i_tcp.c
字号:
,0,(struct sockaddr *)&clientaddress[doomcom->remotenode] ,sizeof(struct sockaddr));// DEBFILE(va("send to %s\n",SOCK_AddrToStr(&clientaddress[doomcom->remotenode]))); // ECONNREFUSED was send by linux port if (c == -1 && errno!=ECONNREFUSED && errno!=EWOULDBLOCK) I_Error ("SOCK_Send sending to node %d (%s): %s",doomcom->remotenode,SOCK_AddrToStr(&clientaddress[doomcom->remotenode]),strerror(errno));}void SOCK_FreeNodenum(int numnode){ // can't disconnect to self :) if(!numnode) return; if( debugfile ) fprintf(debugfile,"Free node %d (%s)\n",numnode,SOCK_AddrToStr(&clientaddress[numnode])); nodeconnected[numnode]=false; // put invalide address memset(&clientaddress[numnode],0,sizeof(clientaddress[numnode]));}//// UDPsocket//SOCKET UDP_Socket (void){ SOCKET s; struct sockaddr_in address; int trueval = true; int i,j; // allocate a socket s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s<0 || s==INVALID_SOCKET) I_Error ("Udp_socket: Can't create socket: %s",strerror(errno)); memset (&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; //Hurdler: I'd like to put a server and a client on the same computer //BP: in fact for client we can use any free port we want i have read // in some doc that connect in udp can do it for us... if ( (i = M_CheckParm ("-clientport"))!=0 ) { if( !M_IsNextParm() ) I_Error("syntax : -clientport <portnum>"); address.sin_port = htons(atoi(M_GetNextParm())); } else address.sin_port = htons(sock_port); if (bind (s, (struct sockaddr *)&address, sizeof(address)) == -1) I_Error ("UDP_Bind: %s", strerror(errno)); // make it non blocking ioctl (s, FIONBIO, &trueval); // make it broadcastable setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&trueval, sizeof(trueval)); j=4; getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&i, (size_t *)&j); // FIXME: so an int value is written to a (char *); portability!!!!!!! CONS_Printf("Network system buffer : %dKb\n",i>>10); if(i < 64<<10) // 64k { i=64<<10; if( setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&i, sizeof(i))!=0 ) CONS_Printf("Can't set buffer lenght to 64k, file transfer will be bad\n"); else CONS_Printf("Network system buffer set to : %d\n",i); } // ip + udp packetheaderlength=20 + 8; // for stats clientaddress[0].ip.sin_family = AF_INET; clientaddress[0].ip.sin_port = htons(sock_port); clientaddress[0].ip.sin_addr.s_addr = INADDR_LOOPBACK; //GetLocalAddress(); // my own ip // inet_addr("127.0.0.1"); // setup broadcast adress to BROADCASTADDR entry clientaddress[BROADCASTADDR].ip.sin_family = AF_INET; clientaddress[BROADCASTADDR].ip.sin_port = htons(sock_port); clientaddress[BROADCASTADDR].ip.sin_addr.s_addr = INADDR_BROADCAST; doomcom->extratics=1; // internet is very high ping SOCK_cmpaddr=UDP_cmpaddr; return s;}SOCKET IPX_Socket (void){ SOCKET s; SOCKADDR_IPX address; int trueval = true; int i,j; // allocate a socket s = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX); if (s<0 || s==INVALID_SOCKET) I_Error ("IPX_socket: Can't create socket: %s",strerror(errno)); memset (&address, 0, sizeof(address));#ifdef LINUX address.sipx_family = AF_IPX; address.sipx_port = htons(sock_port);#else address.sa_family = AF_IPX; address.sa_socket = htons(sock_port);#endif // linux if (bind (s, (struct sockaddr *)&address, sizeof(address)) == -1) I_Error ("IPX_Bind: %s", strerror(errno)); // make it non blocking ioctl (s, FIONBIO, &trueval); // make it broadcastable setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&trueval, sizeof(trueval)); // set receive buffer to 64Kb j=4; getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&i, (size_t *)&j); CONS_Printf("Network system receive buffer : %d\n",i); if(i<128<<10) { i=64<<10; if( setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&i, sizeof(i))!=0 ) CONS_Printf("Can't set receive buffer lenght to 64k, file transfer will be bad\n"); else CONS_Printf("Network system receive buffer set to : %d\n",i); } // ipx header packetheaderlength=30; // for stats // setup broadcast adress to BROADCASTADDR entry#ifdef LINUX clientaddress[BROADCASTADDR].ipx.sipx_family = AF_IPX; clientaddress[BROADCASTADDR].ipx.sipx_port = htons(sock_port); clientaddress[BROADCASTADDR].ipx.sipx_network = 0; for(i=0;i<6;i++) clientaddress[BROADCASTADDR].ipx.sipx_node[i] = (byte)0xFF;#else clientaddress[BROADCASTADDR].ipx.sa_family = AF_IPX; clientaddress[BROADCASTADDR].ipx.sa_socket = htons(sock_port); for(i=0;i<4;i++) clientaddress[BROADCASTADDR].ipx.sa_netnum[i] = 0; for(i=0;i<6;i++) clientaddress[BROADCASTADDR].ipx.sa_nodenum[i] = (byte)0xFF;#endif // linux SOCK_cmpaddr=IPX_cmpaddr; return s;}//Hurdler: temporary addition and changes for master serverstatic int init_tcp_driver = 0;void I_InitTcpDriver(void){ if (!init_tcp_driver) {#ifdef __WIN32__ WSADATA winsockdata; if( WSAStartup(MAKEWORD(1,1),&winsockdata) ) I_Error("No Tcp/Ip driver detected");#endif#ifdef __DJGPP_ if( !__lsck_init() ) I_Error("No Tcp/Ip driver detected");#endif init_tcp_driver = 1; }}void SOCK_CloseSocket( void ){ if( mysocket>=0 ) { //if( server ) // UnregisterServer(); // quick fix bug in libsocket 0.7.4 beta 4 onder winsock 1.1 (win95)#ifndef __DJGPP__ close(mysocket);#endif mysocket = -1; }}void I_ShutdownTcpDriver(void){ if( mysocket!=-1 ) SOCK_CloseSocket(); if ( init_tcp_driver ) {#ifdef __WIN32__ WSACleanup();#endif#ifdef __DJGPP__ __lsck_uninit();#endif init_tcp_driver = 0; }}int SOCK_NetMakeNode (char *hostname){ int newnode; char *localhostname = strdup(hostname); char *portchar; int portnum = htons(sock_port); // retrieve portnum from address ! strtok(localhostname,":"); portchar = strtok(NULL,":"); if( portchar ) portnum = htons(atoi(portchar)); free(localhostname); // server address only in ip if(!ipx) // tcp/ip { struct hostent *hostentry; // host information entry char *t; // remove the port in the hostname as we've it already t = localhostname = strdup(hostname); while ((*t != ':') && (*t != '\0')) t++; *t = '\0'; newnode = getfreenode(); if( newnode == -1 ) return -1; // find ip of the server clientaddress[newnode].ip.sin_family = AF_INET; clientaddress[newnode].ip.sin_port = portnum; clientaddress[newnode].ip.sin_addr.s_addr = inet_addr(localhostname); if(clientaddress[newnode].ip.sin_addr.s_addr==INADDR_NONE) // not a ip ask to the dns { CONS_Printf("Resolving %s\n",localhostname); hostentry = gethostbyname (localhostname); if (!hostentry) { CONS_Printf ("%s unknow\n", localhostname); I_NetFreeNodenum(newnode); free(localhostname); return -1; } clientaddress[newnode].ip.sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; } CONS_Printf("Resolved %s\n",inet_ntoa(*(struct in_addr *)&clientaddress[newnode].ip.sin_addr.s_addr)); free(localhostname); return newnode; } // ipx only return BROADCASTADDR;}boolean SOCK_OpenSocket( void ){ int i; memset(clientaddress,0,sizeof(clientaddress)); for(i=0;i<MAXNETNODES;i++) nodeconnected[i]=false; nodeconnected[0] = true; // always connected to self nodeconnected[BROADCASTADDR] = true; I_NetSend = SOCK_Send; I_NetGet = SOCK_Get; I_NetCloseSocket = SOCK_CloseSocket; I_NetFreeNodenum = SOCK_FreeNodenum; I_NetMakeNode = SOCK_NetMakeNode;#ifdef __WIN32__ // seem like not work with libsocket nor linux :( I_NetCanSend = SOCK_CanSend;#endif // build the socket if(ipx) { mysocket = IPX_Socket (); net_bandwidth = 800000; hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; } else { mysocket = UDP_Socket (); // if (server && cv_internetserver.value) // RegisterServer(mysocket, sock_port); } // for select FD_ZERO(&set); FD_SET(mysocket,&set); return mysocket != -1;}boolean I_InitTcpNetwork( void ){ char serverhostname[255]; boolean ret=0; ipx=M_CheckParm("-ipx"); // initilize the driver I_InitTcpDriver(); I_AddExitFunc (I_ShutdownTcpDriver); if ( M_CheckParm ("-udpport") ) sock_port = atoi(M_GetNextParm()); // parse network game options, if ( M_CheckParm ("-server") ) { server=true; // if a number of clients (i.e. nodes) is specified, the server will wait for the clients to connect before starting // if no number is specified here, the server starts with 1 client, others can join in-game. // since Boris has implemented join in-game, there is no actual need for specifying a particular number here // FIXME: for dedicated server, numnodes needs to be set to 0 upon start if( M_IsNextParm() ) doomcom->numnodes=atoi(M_GetNextParm()); else doomcom->numnodes=1; if (doomcom->numnodes<1) doomcom->numnodes=1; if (doomcom->numnodes>MAXNETNODES) doomcom->numnodes=MAXNETNODES; // server servernode = 0; // FIXME: // ??? and now ? // server on a big modem ??? 4*isdn net_bandwidth = 16000; hardware_MAXPACKETLENGTH = INETPACKETLENGTH; ret = true; } else if( M_CheckParm ("-connect") ) { if(M_IsNextParm()) strcpy(serverhostname,M_GetNextParm()); else serverhostname[0]=0; // assuming server in the LAN, use broadcast to detect it // server address only in ip if(serverhostname[0] && !ipx) { COM_BufAddText("connect \""); COM_BufAddText(serverhostname); COM_BufAddText("\"\n"); // probably modem hardware_MAXPACKETLENGTH = INETPACKETLENGTH; } else { // so we're on a LAN COM_BufAddText("connect any\n"); net_bandwidth = 800000; hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; } } I_NetOpenSocket = SOCK_OpenSocket; return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -