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

📄 ztcp.c

📁 linux下的任天堂模拟器代码。供大家参考。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )http://www.zsnes.comhttp://sourceforge.net/projects/zsneshttps://zsnes.bountysource.comThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseversion 2 as published by the Free Software Foundation.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//**********************************************************\* ZSNES TCP/IP MODULE FOR NETWORK PLAY                     **                                                          ** Coded by the ZSNES team                                  **   TCP/IP drivers coded by _Demo_, revised by Pharos      **   UDP drivers coded by _Demo_, revised by zsKnight       **   Gameplay netplay implementation by zsKnight            **   UDP Packet loss/out of order algorithm/implementation  **     by zsKnight, assistance on normal packets by Pharos  *\**********************************************************/// UDP Algorithm://// UDP Header (1 byte): 1 = Normal Packet w/ reply req, 2 = Reply Packet,//            3 = Gameplay Packet (single byte),//            4 = Gameplay Packet (larger packet), 5 = Re-request gameplay//            packet//// Normal Packets://   Note: The actual implementation turned out to be quite different//         than the below descriptions.//   First byte contains the packet counter, followed by packet contents.//   Remote will send a Reply Packet (just contains packet counter)//   Each packet buffer will have a timer counter which decreases after//     every 1/60 seconds (value set at start is 60).  If this reaches 0//     that packet will be re-sent and reset the timer value back to 60.//   If the local side receives the reply packet, it will set the timer//     counter to -1.//// Gameplay Packets://   Note: Gameplay counter is separate from normal packet counter.//   Note2: When referring to TCP/IP, it refers to the Normal Packets above.//   Each packet in TCP/IP will contain a byte counter when UDP is//     enabled.//   Each UDP packet will contain a byte counter, the number of packets,//     then each packet will contain a byte size only if there are > 1//     packets.  If the packet is just one byte long and contains a value<2,//     it will follow by a byte containing info on how many packets its has//     been like that for (it will not go beyond 32).  If the packet is//     more than one byte long, it will repeat that packet as the extra//     packets for the next 3 packets, with the first byte of those packets//     as the byte counter of that packet, then the second as the size.//     Also, the send data will be stored in a 256*32 byte buffer in case//     of packet loss.//   When receiving, since no UDP packets will exceed 32bytes in length,//     there will be a 256*32 byte buffer and a 256 byte flag buffer.//     The flag clearing pointer will move at an offset of 128 from the//     actual point of the receive buffer.  When it receives data from//     the UDP (or TCP), if the byte count of the data matches the//     receive pointer, it will just send the data directly and increase the//     receive pointer.  Else it will fill the buffer accordingly based on//     the send data (for a maximum of 32 bytes).  Then if the bit on the//     flag buffer is set for the current receive pointer, return the//     appropriate buffer and increase receive pointer.//   In case of packet loss, if no data has been received for every 500ms, the//     local side would send a re-send package request.  What this would//     do is let the remote side build up a package containing all the//     data from the requested send point to the current receive point.//     A resend request will start off with 0x00,0xFF, then the counter//     number.  A resent packet will start off with 0x00,0xFE, the # of//     packets, then the packet data (size of packet, data).  A resend will//     only be done if the requested packet is within the past 64 packets.//   In-game chat will be moved to a separate packet in TCP/IP#ifdef __UNIXSDL__#include "gblhdr.h"#define closesocket(A) close(A)#define CopyMemory(A,B,C) memcpy(A,B,C)#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid())#define UINT unsigned int#define WORD unsigned short#define SOCKET int#define SOCKADDR_IN struct sockaddr_in#define LPSOCKADDR struct sockaddr*#define LPHOSTENT struct hostent*#define HOSTENT struct hostent#define LPINADDR struct in_addr*#define LPIN_ADDR struct in_addr*#define SOCKET_ERROR -1#define INVALID_SOCKET -1#define ioctlsocket ioctl#define FD_SET_VAR fd_set#else#include <stdio.h>#include <time.h>#include <windows.h>#include <winsock.h>#define FD_SET_VAR FD_SET#endifint RecvPtr;int RecvPtr2;unsigned char RecvFlags[256];unsigned char RecvBuffer[256*32];int RecvBufferSize[256];int SendPtr;int SendPtr2;unsigned char SendBuffer[256*32];int SendBufferSize[256];int SendRepeated;int PrevSPacket[16];int PrevSData[16*32];int PrevSSize[16];int PrevSPtr[16];int tcperr;unsigned short portval;int UDPEnable = 1;int UDPConfig = 1;int UDPBackTrace = 6;int blahblahblah = 0;int CounterA = -1;int CounterB = -1;int UDPMode2 = 0;int packetnum,packetnumhead;int packetrecvhead;unsigned char packetdata[2048*16];unsigned char packetrdata[2048*32];int packetconfirm[256];int packetreceived[256];int packetreceivesize[256];int packetsize[256];unsigned char cpacketdata[2048+32];UINT ConnectAddr;int packettimeleft[256];int packetresent[256];int PacketCounter=0;unsigned char CLatencyVal=0;SOCKET   gamesocket;    /* tcp socket for the game */SOCKET   serversocket;  /* tcp socket when the server is listening */SOCKET   ugamesocket;    /* udp socket sending */SOCKET   userversocket;  /* udp socket listening */SOCKADDR_IN    serveraddress; /* address of the server */SOCKADDR_IN    ugameaddress; /* address of the server */SOCKADDR_IN    userveraddress; /* address of the server */char blah[256];char remotehost[256];char hostname[50] = "IP N/A";// Function Prototypesint SendData(int dsize,unsigned char *dptr);int GetData(int dsize,unsigned char *dptr);int GetLeftUDP();/**********************************************************\* Initialize the zsnes tcpip module                        ** - no parameters                                          ** - return 0 on success other value on error               **                                                          ** - no known side effects                                  *\**********************************************************/int InitTCP(){#ifndef __UNIXSDL__   WORD versionneeded = MAKEWORD(2,2);   WSADATA wsadata;#endif   UDPEnable=0;#ifndef __UNIXSDL__   /* Startup winsock */   WSAStartup(versionneeded, &wsadata);   /* Verify version number and exit on wrong version */   if (wsadata.wVersion != versionneeded)   {      return(-1);   }   serversocket=INVALID_SOCKET;#endif   return(0);}/**********************************************************\* Deinitialize the zsnes tcpip module                      ** - no parameters                                          **                                                          ** - no known side effects                                  *\**********************************************************/void DeInitTCP(){#ifndef __UNIXSDL__   WSACleanup();#endif}/**********************************************************\* Gets UDP Status through sending data                     ** - no parameters                                          **                                                          ** - no known side effects                                  *\**********************************************************/void GetUDPStatus() {  int retval;  UDPEnable=UDPConfig;  if (!UDPEnable){    blah[0]=0;    retval = send(gamesocket,blah,1,0);    gethostname(blah,255);    retval = send(gamesocket,blah,strlen(blah),0);  }  else {    blah[0]=1;    retval = send(gamesocket,blah,1,0);    gethostname(blah,255);    retval = send(gamesocket,blah,strlen(&blah[1])+1,0);  }  retval = recv(gamesocket,blah,256,0);  if (blah[0]==0) UDPEnable=0;  retval = recv(gamesocket,blah,256,0);}/**********************************************************\* Connect to game server                                   ** - parameters                                             **     - pointer server name                                **     - server port                                        ** - return 0 on success other value on error               **                                                          ** - no known side effects                                  *\**********************************************************/int isipval(char *name){  int i=0;  while(name[i]!=0){    if (!((name[i]=='.') || ((name[i]>='0') && (name[i]<='9'))))      return(0);    i++;  }  return(1);}int ConnectServer(char *servername, unsigned int port){   char blah[255];   int retval,i;   LPHOSTENT host1=NULL;   int yesip;   packetnum = 0;   packetnumhead = 0;   packetrecvhead = 0;   RecvPtr = 0;   SendPtr = 0;   RecvPtr2 = 0;   SendPtr2 = 0;   ConnectAddr = 0;   SendRepeated = 0;   for (i=0;i<16;i++)     PrevSPacket[i]=0;   /* get host and verify if it is valid */   yesip = isipval(servername);   if (!yesip){     host1 = gethostbyname(servername);     if (host1 == NULL)     {        return(-1);     }   }//   return(-1);   if (UDPConfig) UDPEnable = 1;   if (UDPEnable)   {      PacketCounter=1;      for (i=0;i<256;i++) {packettimeleft[i]=-1; packetconfirm[i]=1; packetreceived[i]=0; RecvFlags[i]=0;}      userveraddress.sin_family = AF_INET;      ugameaddress.sin_family = AF_INET;      if (!yesip)      {         ugameaddress.sin_addr = *( (LPIN_ADDR) *host1->h_addr_list );      }      else      {         ugameaddress.sin_addr.s_addr = inet_addr(servername);      }      ConnectAddr = ugameaddress.sin_addr.s_addr;      userveraddress.sin_addr.s_addr = INADDR_ANY;//      port++;      ugameaddress.sin_port = htons((unsigned short) port);      userveraddress.sin_port = htons((unsigned short) port);//      port--;      userversocket = socket(AF_INET, SOCK_DGRAM,0);      ugamesocket = socket(AF_INET, SOCK_DGRAM,0);      if (ugamesocket == INVALID_SOCKET)      {#ifdef __UNIXSDL__         STUB_FUNCTION;#else                 tcperr=WSAGetLastError();                 sprintf(blah,"Could not initialize UDP(2) : %d",tcperr);                 MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK);#endif                 return(-2);      }      if (userversocket == INVALID_SOCKET)      {#ifdef __UNIXSDL__         STUB_FUNCTION;#else                 tcperr=WSAGetLastError();                 sprintf(blah,"Could not initialize UDP(2.5) : %d",tcperr);                 MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK);#endif       return(-2);      }      if (bind(userversocket,(struct sockaddr*)&userveraddress,sizeof(userveraddress))==          SOCKET_ERROR)      {#ifdef __UNIXSDL__         STUB_FUNCTION;#else         tcperr=WSAGetLastError();         sprintf(blah,"Could not initialize UDP(16) : %d",tcperr);         MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK);#endif         return(-2);      }//      blah[0]=1;//      retval = sendto(ugamesocket,blah,1,0,(struct sockaddr*)&ugameaddress,sizeof(struct sockaddr));//      if (retval == SOCKET_ERROR) return(-1);      blah[0]=1;      SendData(1,blah);//      retval = sendto(ugamesocket,blah,5,0,(struct sockaddr*)&ugameaddress,sizeof(struct sockaddr));//      blah[0]=0;//      i = sizeof(struct sockaddr);//      retval = recvfrom(userversocket,blah,5,0,(struct sockaddr*)&userveraddress,&i);//      MessageBox(NULL,blah,//              "Error",//              MB_SYSTEMMODAL|MB_OK);      return(0);//      retval = send(gamesocket,blah,1,0);//      retval = recv(gamesocket,blah,1,0);   }   /* create the game socket and verify if it is valid */   gamesocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   if (gamesocket == INVALID_SOCKET)   {      return(-2);   }   /* initialize server address */   serveraddress.sin_family = AF_INET;   if (!yesip)     serveraddress.sin_addr = *( (LPIN_ADDR) *host1->h_addr_list );   else     serveraddress.sin_addr.s_addr = inet_addr(servername);   serveraddress.sin_port = htons((unsigned short)port);   /* try to connect to the server */   retval = connect( gamesocket,                     (LPSOCKADDR)&serveraddress,                     sizeof(struct sockaddr));   if (retval == SOCKET_ERROR)   {#ifdef __UNIXSDL__      STUB_FUNCTION;

⌨️ 快捷键说明

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