www.pudn.com > VOIP_server_client.rar > peer1_sock.cpp


#include "peer1_sock.h" 
#include  
#include "peer1_main.h" 
#include "peer1_resource.h" 
#include "peer1_sound_cap.h" 
#include "peer1_sound_play.h" 
 
// Constants =================================================================== 
#define BUF_SIZE 256      // Total packet length 
#define DATA_LEN 252      // Sound data length,  256-252=4 is header length 
#define F_BUF_SIZE 6250 
#define MAJOR_VERSION_REQUIRED 1 
#define MINOR_VERSION_REQUIRED 1 
 
//  Global Variables =========================================================== 
int achOutBuf[BUF_SIZE]; /* output buffer */ 
int  achInBuf[BUF_SIZE]; /*input buffer */ 
int *achInBufP=achInBuf;   // Input buffer pointer 
int *achOutBufP=achOutBuf;   // Output buffer pointer 
char InBuffChar[1024];        // Input medium char buffer 
char OutBuffChar[1024];       // Output  medium char buffer 
 
int outTextBuf[BUF_SIZE];     // input and output buffers for Text socket 
int inTextBuf[BUF_SIZE]; 
int *outTextBufP=outTextBuf; 
int *inTextBufP=inTextBuf; 
char outTextBufChar[1024]; 
char inTextBufChar[1024];     // 
 
int right_rcvSeq = 0; 
int mostRecentSound[DATA_LEN];  // Most recent sound data used when package loss 
 
float clk_sd; 
float clk_rc; 
float du; 
int sd_clk_times; 
 
struct sdRTP 
      { 
        int sdTS; 
        int sdTS_ms; 
        int sdSeq; 
        int sdLen; 
      }sdRtp; 
struct sdRTP *sdRtpP=&sdRtp;     // Send packet header structure 
int old_sdSeq; 
 
struct rcvRTP 
      { 
        int rcvTS; 
        int rcvTS_ms; 
        int rcvSeq; 
        int rcvLen; 
 
      } rcvRtp;               // Receive header structure 
struct sdTextHEADER 
      { 
       int Ctrl_Flag; 
       int Ask_Con; 
       int Aws_Con; 
       int Ask_Discon; 
       int Aws_Discon; 
      } sdTextHeader; 
struct sdTextHEADER *sdTextHeaderP = &sdTextHeader;  // Text send header 
 
struct rcvTextHEADER 
      { 
       int Ctrl_Flag; 
       int Ask_Con; 
       int Aws_Con; 
       int Ask_Discon; 
       int Aws_Discon; 
      } rcvTextHeader;                     // Text receive header 
 
 
int nReturnCode; 
WSADATA wsaData; 
 
int nRet; 
SOCKET s_snd;    //For sending 
int nRet1; 
SOCKET s_rcv;   //For receiving; 
int nRet2; 
SOCKET s_text;  // For text 
int totalLen;               // receive total length 
int  f_buf[F_BUF_SIZE];     // buffer between input buffer and play_buffer 
int *f_bufP=f_buf; 
int rcv_file_num=0;      // Counter for marker share array and play buffer 
char st02[100]; 
float num_of_trans; 
float late_arrive_skip, num_of_rcv, num_of_mRecent, too_long_skip; 
int TS_old; 
int TS_delay; 
int first_rcv; 
 
// External Global Variables =================================================== 
extern BOOL thread1_stop,thread2_stop,thread3_stop,thread4_stop; 
struct play_buffer{ 
                   char play_data[PLAY_LENGTH]; 
                   }; 
extern struct play_buffer my_play_buffer[PLAY_BUF_LEN]; 
extern int share_array_rcv[PLAY_BUF_LEN]; 
extern float TS_cap; 
// Temp Variables ============================================================== 
 
 
 
 
//------------------------------------------------------- 
//*************** pr1() ********************************* 
//------------------------------------------------------- 
void pr1(HWND hwndDlg, char *st) 
{ 
 
  Display(st); 
} 
 
//-------------------------------------------------------------- 
//**************** WSA STARTUP ******************************* 
//--------------------------------------------------------------- 
int wsa_start(HWND hwndDlg, int err_restart) 
{ 
        first_rcv = 0; 
        TS_old = 0; 
        sdRtp.sdSeq=0; 
        sd_clk_times = 0; 
        rcv_file_num=0; 
        right_rcvSeq = 0; 
        TS_delay = delay_limit; 
 
        if (err_restart == 0) 
        { 
        late_arrive_skip = 0; 
        too_long_skip = 0; 
        num_of_trans = 0; 
        num_of_rcv = 0; 
        num_of_mRecent = 0; 
        } 
 
	// Prepare version for WSAStartup() 
	WORD wVersionRequired = MAKEWORD(MAJOR_VERSION_REQUIRED, 
                                         MINOR_VERSION_REQUIRED); 
     
	// Initialize the WinSock DLL 
	nReturnCode = WSAStartup(wVersionRequired, &wsaData); 
	if (nReturnCode != 0 )  
	{ 
		MessageBox(NULL,"Error on WSAStartup()", 
					"Startup Error", MB_OK); 
    	return (0); 
	} 
	 
	// Confirm that the version requested is available. 
	if (wsaData.wVersion != wVersionRequired) 
	{ 
    	// Version needed is not available. 
		MessageBox(NULL,"Wrong WinSock Version", 
					"Version Error", MB_OK); 
    	WSACleanup(); 
    	return (0); 
	} 
        else 
        { 
        //pr1(hwndDlg, "WSA_startup OK!\r\n"); 
        return (1); 
        } 
} 
 
// ----------------------------------------------------------------------------- 
//******** Creating sending socket ********************************************* 
//------------------------------------------------------------------------------ 
void Connect_snd( HWND hwndDlg, WPARAM wParam, LPARAM lParam, char *ip) 
{ 
          SOCKADDR_IN stRmtAddr; 
 
        /* ------opening a UDP soctet using socket() function*/ 
 
        if (s_snd != INVALID_SOCKET) 
        { 
        nRet=closesocket(s_snd); 
        s_snd=INVALID_SOCKET; 
        } 
        else 
        { 
        MessageBox(hwndDlg, 
                            "Invalid send Socket.", 
                                "Opening error-1", MB_OK); 
         } 
 
 
         s_snd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
 
        if (s_snd != INVALID_SOCKET) 
        { 
        //pr1(hwndDlg,"---send socket opening ok!\r\n"); 
        } 
        else { 
                 MessageBox(hwndDlg, 
                            "Send socket opening error.", 
                                "Opening error-2", MB_OK); 
             } 
 
 
 
/* --------request notification for connect,read, write, and close events. 
     and automatically make socket nonblocking)*/ 
     nRet=WSAAsyncSelect(s_snd, hwndDlg, SM_ASYNC, 
                         FD_READ | FD_WRITE); 
     if (nRet != SOCKET_ERROR){ 
        //pr1(hwndDlg,"send socket  async ok!\r\n"); 
        } 
        else { 
              MessageBox(hwndDlg, 
                            "Send Socket Async Error.", 
                                "Opening error-3", MB_OK); 
              } 
 
    /* ----Remote IP and Port number for s_snd */ 
        stRmtAddr.sin_family = AF_INET; 
        stRmtAddr.sin_port = htons(1794); 
        stRmtAddr.sin_addr.s_addr = inet_addr(ip); 
    /* ----------connect--------- */ 
    nRet=connect(s_snd,  (LPSOCKADDR)&stRmtAddr, sizeof (struct sockaddr)); 
    if (nRet != SOCKET_ERROR) { 
        //pr1(hwndDlg,"connected to the destination ok!\r\n"); 
         } 
    else { 
           MessageBox(hwndDlg, 
           "Connection failed.", 
           "connection error", MB_OK); 
             } 
} 
 
//------------------------------------------------------------------------------ 
//************* Creating Receiving Socket ************************************** 
//------------------------------------------------------------------------------ 
void Connect_rcv( HWND hwndDlg, WPARAM wParam, LPARAM lParam) 
{ 
          SOCKADDR_IN stLclAddr; 
 
        /* ------opening a UDP soctet using socket() function*/ 
         if (s_rcv != INVALID_SOCKET) 
        { 
        nRet1=closesocket(s_rcv); 
        s_rcv=INVALID_SOCKET; 
        } 
        else 
        { 
        MessageBox(hwndDlg, "Invalid Receive Socket.", 
                            "Opening error-1", MB_OK); 
         } 
         s_rcv=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
 
        if (s_rcv != INVALID_SOCKET) 
        { 
        //pr1(hwndDlg,"---Receive socket opening ok!\r\n"); 
        } 
        else { 
                 MessageBox(hwndDlg, "Receive socket openning error.", 
                                     "Opening error-2", MB_OK); 
             } 
 
/* --------request notification for connect,read, write, and close events. 
     and automatically make socket nonblocking)*/ 
     nRet1=WSAAsyncSelect(s_rcv, hwndDlg, SM_ASYNC, FD_READ | FD_WRITE); 
     if (nRet1 != SOCKET_ERROR) 
        { 
           //pr1(hwndDlg,"Receive Socket  Async ok!\r\n"); 
        } 
        else 
             { 
               MessageBox(hwndDlg, "Receive Socket Async Error.", 
                                  "Opening error-3", MB_OK); 
              } 
 
      /* ----Local IP and port number for s_rcv*/ 
    stLclAddr.sin_family = PF_INET; 
    stLclAddr.sin_port = htons(1794); 
    stLclAddr.sin_addr.s_addr = inet_addr(LOC_ADDRESS); 
    nRet1 = bind(s_rcv,(LPSOCKADDR)&stLclAddr, sizeof(struct sockaddr)); 
    if (nRet1 == SOCKET_ERROR) { 
        pr1(hwndDlg,"Receive socket bind failed!\r\n"); 
        } 
       
} 
 
//------------------------------------------------------------------------------ 
// ******************** Creating Text Socket *********************************** 
//------------------------------------------------------------------------------ 
void Connect_text( HWND hwndDlg, WPARAM wParam, LPARAM lParam, char *ip) 
{ 
          SOCKADDR_IN stLclAddr; 
          SOCKADDR_IN stRmtAddr; 
 
        /* ------opening a UDP soctet using socket() function*/ 
 
        if (s_text != INVALID_SOCKET) 
        { 
        nRet2=closesocket(s_text); 
        s_text=INVALID_SOCKET; 
        } 
         s_text=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
        if (s_text != INVALID_SOCKET) 
        { 
        //Display("---text socket opening ok!\r\n"); 
        } 
        else { 
                 MessageBox(hwndDlg, 
                            "Text Socket openning error.", 
                                "POP Info", MB_OK); 
             } 
 
/* --------request notification for connect,read, write, and close events. 
     and automatically make socket nonblocking)*/ 
     nRet2=WSAAsyncSelect(s_text, hwndDlg, SM_ASYNC_TEXT, 
                         FD_READ | FD_WRITE); 
     if (nRet2 != SOCKET_ERROR){ 
        //Display("Text socket  async ok!\r\n\r\n"); 
        } 
        else { 
              MessageBox(hwndDlg, 
                            "Text Socket async error.", 
                                "POP Info", MB_OK); 
              } 
 
       /* ----name the socket, to receive requests as a server*/ 
    stLclAddr.sin_family = AF_INET; 
    stLclAddr.sin_port = htons(1790); 
    stLclAddr.sin_addr.s_addr = inet_addr(LOC_ADDRESS); 
    nRet2 = bind(s_text,(LPSOCKADDR)&stLclAddr, sizeof(struct sockaddr)); 
    if (nRet != SOCKET_ERROR) { 
        //Display("Text socket bind ok!\r\n"); 
        } 
 
    else { 
           MessageBox(hwndDlg, 
           "Text Socket naming error.", 
           "POP Info", MB_OK); 
             } 
 
    /* ----name the socket, to receive requests as a client */ 
        stRmtAddr.sin_family = AF_INET; 
        stRmtAddr.sin_port = htons(1792); 
        stRmtAddr.sin_addr.s_addr = inet_addr(ip); 
        //Display("Naming the destination... \r\n\r\n"); 
 
    /* ----------connect--------- */ 
    nRet2=connect(s_text,  (LPSOCKADDR)&stRmtAddr, sizeof (struct sockaddr)); 
    if (nRet2 != SOCKET_ERROR) { 
        //Display("Text connected to the destination ok!\r\n\r\n"); 
         } 
    else { 
           MessageBox(hwndDlg, 
           "Text Connection failed.", 
           "POP Info", MB_OK); 
             } 
} 
 
//------------------------------------------------------------------------------ 
//*********************** Sending Control(Through text sockrt) ***************** 
//------------------------------------------------------------------------------ 
void Send_Control(HWND hwndDlg, int ask_con, 
              int aws_con, int ask_discon,int aws_discon) 
{ 
  // Copy send text headre into the text output buffer 
  sdTextHeader.Ctrl_Flag = 1; 
  sdTextHeader.Ask_Con = ask_con; 
  sdTextHeader.Aws_Con = aws_con; 
  sdTextHeader.Ask_Discon = ask_discon; 
  sdTextHeader.Aws_Discon = aws_discon; 
  memset(outTextBuf, 0, sizeof(outTextBuf)); 
  memcpy(outTextBufP, sdTextHeaderP,sizeof(struct sdTextHEADER)); 
 
  // sending 
  memset(outTextBufChar, 0, sizeof(outTextBufChar)); 
  memcpy(outTextBufChar,outTextBuf,sizeof(outTextBuf)); 
  nRet = send(s_text, outTextBufChar, 1024, 0); 
} 
 
//------------------------------------------------------------------------------ 
//*********************** Sending Clk (Through text sockrt) (not used) ********* 
//------------------------------------------------------------------------------ 
void Send_Clk(HWND hwndDlg,int ctrl_flag, int ask_con, 
              int aws_con, int ask_discon,int aws_discon) 
{ 
  // Copy send text headre into the text output buffer 
  sdTextHeader.Ctrl_Flag = ctrl_flag; 
  sdTextHeader.Ask_Con = ask_con; 
  sdTextHeader.Aws_Con = aws_con; 
  sdTextHeader.Ask_Discon = ask_discon; 
  sdTextHeader.Aws_Discon = aws_discon; 
  memset(outTextBuf, 0, sizeof(outTextBuf)); 
  memcpy(outTextBufP, sdTextHeaderP,sizeof(struct sdTextHEADER)); 
 
  // sending 
  memset(outTextBufChar, 0, sizeof(outTextBufChar)); 
  memcpy(outTextBufChar,outTextBuf,sizeof(outTextBuf)); 
  clk_sd = clock(); 
  nRet = send(s_text, outTextBufChar, 1024, 0); 
} 
 
 
//-------------------------------------------------------- 
//************** Sending message ************************* 
//-------------------------------------------------------- 
void Send_Msg(HWND hwndDlg,char *gszMsg) 
{ 
 
     //***copy send text header into the text output buffer 
     sdTextHeader.Ctrl_Flag = 0; 
     sdTextHeader.Ask_Con = 0; 
     sdTextHeader.Aws_Con = 0; 
     sdTextHeader.Ask_Discon = 0; 
     sdTextHeader.Aws_Discon = 0; 
     memset(outTextBuf, 0, sizeof(outTextBuf)); 
     memcpy(outTextBufP,sdTextHeaderP,sizeof(struct sdTextHEADER)); 
 
     //***copy text message into the output buffer 
     outTextBufP=outTextBufP+5; 
     memcpy(outTextBufP,gszMsg,strlen(gszMsg)); 
     outTextBufP=outTextBufP-5; 
 
     memset(outTextBufChar, 0, sizeof(outTextBufChar)); 
     memcpy(outTextBufChar,outTextBuf,sizeof(outTextBuf)); 
     nRet = send(s_text, outTextBufChar, 1024, 0); 
 
} 
 
//---------------------------------------------------------------------------- 
//******************** sending files ***************************************** 
//---------------------------------------------------------------------------- 
int send_file(HWND hwndDlg, char *Sound_Data) 
{ 
 
         achOutBufP=achOutBufP+4; 
         memcpy(achOutBufP,Sound_Data,CAP_LENGTH); //put part of file into out buf 
         achOutBufP=achOutBufP-4; 
 
         sdRtp.sdTS = TS_cap; 
         sdRtp.sdLen = CAP_LENGTH; 
         memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header 
 
         ////////////////////////////// 
         //*** Debugging-6 Simulate Out-of-sequence 
         // Uncomment the following lines to simulate Out-of-sequence problems 
         /*int old_sdSeq; 
         if (sdRtp.sdSeq%100==3) 
         { 
          old_sdSeq = sdRtp.sdSeq; 
          sdRtp.sdSeq = sdRtp.sdSeq+2;                  // Simulate packate loss 
          memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header 
          sdRtp.sdSeq = old_sdSeq; 
         } 
         if (sdRtp.sdSeq%100==4) 
         { 
          old_sdSeq = sdRtp.sdSeq; 
          sdRtp.sdSeq = sdRtp.sdSeq-1;                  // Simulate packate loss 
          memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header 
          sdRtp.sdSeq = old_sdSeq; 
         } 
         if (sdRtp.sdSeq%100==5) 
         { 
          old_sdSeq = sdRtp.sdSeq; 
          sdRtp.sdSeq = sdRtp.sdSeq-1;                  // Simulate packate loss 
          memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header 
          sdRtp.sdSeq = old_sdSeq; 
         }     */ 
          
         //sprintf(st02, "Seq = %d ", sdRtp.sdSeq); 
         //Display(st02); 
         /////////////////////////////// 
           
         sdRtp.sdSeq = (sdRtp.sdSeq + 1) % 65536; 
         memset(OutBuffChar, 0, sizeof(OutBuffChar)); 
         memcpy(OutBuffChar,achOutBuf,sizeof(achOutBuf)); 
 
         nRet = send(s_snd, OutBuffChar, 1024, 0); 
         num_of_trans++; 
 
         return (1); 
 
} 
 
//-------------------------------------------------------- 
//************* Handling Async Message ******************* 
//-------------------------------------------------------- 
void HandleAsyncMsg( HWND hwndDlg, WPARAM wParam, LPARAM lParam) 
{ 
 
	switch(WSAGETSELECTEVENT(lParam)) 
	{ 
		case FD_CONNECT: 
			//pr1(hwndDlg,"FD_CONNECT notification received\r\n"); 
			break; 
 
		case FD_WRITE: 
			//Display("FD_WRITE notification received\r\n"); 
			break; 
			 
		case FD_READ: 
                        if(thread1_stop==TRUE || thread2_stop==TRUE 
                           || thread3_stop==TRUE || thread4_stop==TRUE) 
                        break; 
 
                        else 
                        { 
                        rec_file(hwndDlg); 
			break; 
                        } 
 
		case FD_CLOSE: 
			pr1(hwndDlg,"FD_CLOSE notification received\r\n"); 
			break; 
	} 
} 
 
//------------------------------------------------------------------------------ 
//************* Handling Async Message For Text ******************************** 
//------------------------------------------------------------------------------ 
void HandleAsyncMsg_Text( HWND hwndDlg, WPARAM wParam, LPARAM lParam) 
{ 
 
	switch(WSAGETSELECTEVENT(lParam)) 
	{ 
		case FD_CONNECT: 
			//pr1(hwndDlg,"Text FD_CONNECT notification received\r\n"); 
			break; 
 
		case FD_WRITE: 
			//Display("Text FD_WRITE notification received\r\n"); 
			break; 
			 
		case FD_READ: 
                        //Display("Text FD_READ notification received\r\n"); 
                        rec_text(hwndDlg); 
			break; 
 
 
		case FD_CLOSE: 
			pr1(hwndDlg,"Text FD_CLOSE notification received\r\n"); 
			break; 
	} 
} 
 
//-------------------------------------------------------- 
//****************Close all socket************************ 
//-------------------------------------------------------- 
void Close_all_socket() 
{ 
  CloseSocket(s_rcv); 
  CloseSocket(s_snd); 
 
} 
 
//-------------------------------------------------------- 
//**************** Closing Socket ************************ 
//-------------------------------------------------------- 
void CloseSocket(SOCKET sock) 
{    
	int nRet; 
	char szBuf[255]; 
	 
 
	shutdown(sock, 1); 
       while(1) 
	{ 
 
		nRet = recv( 
				sock, 
				szBuf, 
				sizeof(szBuf), 
				0); 
 
		if (nRet == 0 || nRet == SOCKET_ERROR) 
			break; 
	} 
 
	shutdown(sock, 2); 
	closesocket(sock); 
} 
 
//------------------------------------------------------------------------------ 
//******************** receive_text and Control messages *********************** 
//------------------------------------------------------------------------------ 
void rec_text(HWND hwndDlg) 
{ 
    memset(inTextBufChar, 0, sizeof(inTextBufChar)); 
    nRet2=recv (s_text, inTextBufChar, sizeof(inTextBufChar), 0); 
    memset(inTextBuf, 0, sizeof(inTextBuf)); 
    memcpy(inTextBuf,inTextBufChar,sizeof(inTextBufChar)); 
 
    rcvTextHeader.Ctrl_Flag = inTextBuf[0]; 
    rcvTextHeader.Ask_Con = inTextBuf[1]; 
    rcvTextHeader.Aws_Con = inTextBuf[2]; 
    rcvTextHeader.Ask_Discon = inTextBuf[3]; 
    rcvTextHeader.Aws_Discon = inTextBuf[4]; 
    /*char st10[150]; 
    sprintf(st10,"Ask_Con = %d Aws_Con = %d Ask_Discon = %d Aws_Discon = %d\r\n", 
       rcvTextHeader.Ask_Con,rcvTextHeader.Aws_Con, 
        rcvTextHeader.Ask_Discon,rcvTextHeader.Aws_Discon); 
    Display(st10);*/ 
    //************** Display Text ******* 
    if( rcvTextHeader.Ctrl_Flag == 0 && 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
         inTextBufP=inTextBufP+5; 
         Display(inTextBufP); 
         inTextBufP=inTextBufP-5; 
         pr1(hwndDlg,"\r\n\r\n"); 
        } 
    //************** Received Answers ******** 
 
    if( rcvTextHeader.Ctrl_Flag == 1 &&        // ***** Accept invitation (by remote) 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==1 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
        SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_L_START, (LPARAM) 0); 
        pr1(hwndDlg,"The invitation has been accepted. Talk channel has been established.\r\n"); 
        } 
    if( rcvTextHeader.Ctrl_Flag == 1 &&        // ***** Accept invitation (by remote) due to error 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==2 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
        SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_L_ERR_START, (LPARAM) 0); 
        } 
 
    if( rcvTextHeader.Ctrl_Flag == 1 &&        // *****  not Accept invitation (by remote) 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==99 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
          pr1(hwndDlg,"The invitation has been refused\r\n"); 
          SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_STOP, (LPARAM) 0); 
        } 
 
    if( rcvTextHeader.Ctrl_Flag == 1 &&        // *****  Disconnection (occurred at remote) 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==1) 
        { 
          pr1(hwndDlg,"The talk channel has been disconnected\r\n"); 
        } 
    if( rcvTextHeader.Ctrl_Flag == 1 &&        // *****  Disconnection (by error) 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==2) 
        { 
         SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_START, (LPARAM) 0); 
        } 
 
    //*************** Sending answer ****** 
     if( rcvTextHeader.Ctrl_Flag == 1 &&                // **** Being invited 
        rcvTextHeader.Ask_Con==1 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
         char st25[100]; 
         sprintf(st25, "You are being invited for a talk.\r\n"); 
         int ans; 
         ans=MessageBox(hwndDlg, 
                                   st25, 
                                   "Invitation", MB_YESNO); 
         if (ans==IDNO)                                    // **** Say no 
         {                                                 // sending Aws_Con=99 to remote 
           Display("Talk channel was not established\r\n"); 
           Send_Control(hwndDlg, 0,99,0,0); 
         } 
         else 
         {                                   // **** Say yes 
         Send_Control(hwndDlg, 0,1,0,0);     // **** Sending Aws_Con=1 to remote 
         SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_START, (LPARAM) 0); 
         Display("Talk channel has been established\r\n"); 
         } 
        } 
 
        if( rcvTextHeader.Ctrl_Flag == 1 &&                // **** Being invited (due to remote error) 
        rcvTextHeader.Ask_Con==2 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
         Send_Control(hwndDlg, 0,2,0,0);     // **** Sending Aws_Con=2 to remote 
         SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_ERR_START, (LPARAM) 0); 
        } 
 
        if( rcvTextHeader.Ctrl_Flag == 1 &&     // After disconnected by remote, ack 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==1 && rcvTextHeader.Aws_Discon==0) 
        { 
          SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_STOP, (LPARAM) 0); 
          Display("Talk channel has been disconnected\r\n"); 
          Send_Control(hwndDlg, 0,0,0,1);        // ***** Aws_Discon=1 
        } 
 
        if( rcvTextHeader.Ctrl_Flag == 1 &&     // After disconnected by remote(by error) ack 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==2 && rcvTextHeader.Aws_Discon==0) 
        { 
          SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_ERR_STOP, (LPARAM) 0); 
          Display("Talk channel has been disconnected(due to a remote site error).\r\n"); 
          Send_Control(hwndDlg, 0,0,0,2);        // ***** Aws_Discon=2 
        } 
 
         // **** receice send_clk 
         if( rcvTextHeader.Ctrl_Flag == 99 &&       
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
         Send_Clk(hwndDlg,100,0,0,0,0); 
         } 
 
 
        // **** when receive path delay clk sent back by remote 
        if( rcvTextHeader.Ctrl_Flag == 100 &&     // clk_rc 
        rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && 
        rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) 
        { 
          if(sd_clk_times < 10) 
          { 
          clk_rc = clock(); 
          du = clk_rc - clk_sd; 
          char st10[50]; 
          sprintf(st10, "clk_sd = %f, clk_rc = %f, du/2 = %f\r\n", clk_sd, clk_rc,du/2); 
          Display(st10); 
          Send_Clk(hwndDlg,99,0,0,0,0); 
          sd_clk_times++; 
          } 
        } 
 
} 
 
 
//--------------------------------------------------------------------------- 
//*********************** receive_file ************************************** 
//--------------------------------------------------------------------------- 
int rec_file(HWND hwndDlg) 
{ 
           int sleep_time; 
 
           memset(InBuffChar, 0, sizeof(InBuffChar)); 
           nRet=recv (s_rcv, InBuffChar, sizeof(InBuffChar), 0); 
 
           memset(achInBuf, 0, sizeof(achInBuf)); 
           memcpy(achInBuf,InBuffChar,sizeof(InBuffChar)); 
 
           rcvRtp.rcvTS = achInBuf[0]; 
           rcvRtp.rcvSeq = achInBuf[2]; 
           rcvRtp.rcvLen = achInBuf[3]; 
 
           //////////////////// 
           //*** Debugging-7 Print sequence numbers of packets received 
           //sprintf(st02, "%d ", rcvRtp.rcvSeq); 
           //pr1(hwndDlg, st02); 
           /////////////////// 
 
           //////////////// 
           if(++first_rcv > 1) 
           { 
           TS_delay = rcvRtp.rcvTS - TS_old; 
           } 
           TS_old = rcvRtp.rcvTS; 
 
           if( (++first_rcv > 1) && (TS_delay < delay_limit) ) 
           { 
              sleep_time =  delay_limit-TS_delay; 
            
              while ( sleep_time > 5) 
              { 
                Sleep(5); 
                sleep_time = sleep_time-5; 
              } 
 
              Sleep(sleep_time); 
 
              handle_seq(hwndDlg); 
           } 
           else{ 
 
           if( (++first_rcv > 1) && (TS_delay > too_long_limit) ) 
           { 
              //*** Debugging-8 Print too_long_skips 
              //pr1(hwndDlg, "  "); 
              num_of_rcv++; 
              too_long_skip++; 
 
             achInBufP=achInBufP+4; 
             memcpy(f_bufP,achInBufP,rcvRtp.rcvLen); 
             memcpy(mostRecentSound,achInBufP,rcvRtp.rcvLen); 
             achInBufP=achInBufP-4; 
 
             if(rcvRtp.rcvSeq == right_rcvSeq) 
             right_rcvSeq = (right_rcvSeq+1)%65536; 
 
             if(rcvRtp.rcvSeq > right_rcvSeq) 
             { 
             right_rcvSeq = rcvRtp.rcvSeq; 
             right_rcvSeq = (right_rcvSeq+1)%65536; 
             } 
           } 
           else 
           { 
             /////////////// Sequence No.  ///////////////////// 
               handle_seq(hwndDlg); 
 
 
              /////////////////////////////////////////////////////////// 
              }//(too_long_skip else) 
             } //(short sleep else) 
 
 
     return (1); 
  } 
 
//------------------------------------------------------------------- 
//************** Handle sequence No. ******************************** 
//------------------------------------------------------------------- 
void handle_seq(HWND hwndDlg) 
{ 
if(rcvRtp.rcvSeq < right_rcvSeq) 
             { 
              //*** Debugging-9 Print late_arrive_skips 
              //pr1(hwndDlg, "  "); 
              late_arrive_skip++; 
              num_of_rcv++; 
              } 
 
             if(rcvRtp.rcvSeq == right_rcvSeq)        //*** IF rcvRtp.rcvSeq == right_rcvSeq 
             { 
             num_of_rcv++; 
 
             achInBufP=achInBufP+4; 
             memcpy(f_bufP,achInBufP,rcvRtp.rcvLen); 
             memcpy(mostRecentSound,achInBufP,rcvRtp.rcvLen); 
             achInBufP=achInBufP-4; 
 
             right_rcvSeq = (right_rcvSeq+1)%65536; 
 
              memset(my_play_buffer[rcv_file_num].play_data, 0, PLAY_LENGTH); 
              memcpy(my_play_buffer[rcv_file_num].play_data, f_buf, PLAY_LENGTH); 
              if (share_array_rcv[rcv_file_num]==1) 
                { 
 
                  pr1(hwndDlg, "**** error: share_array_rcv[rcv_file_num]==1\r\n"); 
                  SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_STOP, (LPARAM) 0); 
 
                } 
              else 
                { 
                  share_array_rcv[rcv_file_num]=1; 
                  rcv_file_num++; 
                  if(rcv_file_num==PLAY_BUF_LEN) 
                  rcv_file_num=0;                   // ** wrap the buffer 
                } 
             } 
 
             if(rcvRtp.rcvSeq > right_rcvSeq)         //*** IF rcvRtp.rcvSeq > right_rcvSeq 
              { 
              num_of_rcv++; 
 
 
               memcpy(f_bufP,mostRecentSound,rcvRtp.rcvLen); 
 
 
               for(int j=0; j< rcvRtp.rcvSeq-right_rcvSeq; j++)      //--Use most recent data 
               { 
               num_of_mRecent++; 
               //*** Debugging-10 Print "most recent data".(when any lost packet recovery occurs) 
               //pr1(hwndDlg, "  "); 
              memset(my_play_buffer[rcv_file_num].play_data, 0, PLAY_LENGTH); 
              memcpy(my_play_buffer[rcv_file_num].play_data, f_buf, PLAY_LENGTH); 
              if (share_array_rcv[rcv_file_num]==1) 
                { 
                  pr1(hwndDlg, "**** error: share_array_rcv[rcv_file_num]==1\r\n"); 
                  SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_STOP, (LPARAM) 0); 
                } 
              else 
                { 
                  share_array_rcv[rcv_file_num]=1; 
                  rcv_file_num++; 
                  if(rcv_file_num==PLAY_BUF_LEN) 
                  rcv_file_num=0; 
                } 
              }                               //--End of using most recent data 
 
              right_rcvSeq = rcvRtp.rcvSeq; 
              right_rcvSeq = (right_rcvSeq+1)%65536;    //update right_rcvSeq 
              //*** Debugging-11 Print "current data".(when any lost packet recovery occurs) 
              //pr1(hwndDlg, "  "); 
              achInBufP=achInBufP+4;           //-- Fill the current(bigger Seq) data 
             memcpy(f_bufP,achInBufP,rcvRtp.rcvLen); 
             memcpy(mostRecentSound,achInBufP,rcvRtp.rcvLen); 
             achInBufP=achInBufP-4; 
 
 
 
              memset(my_play_buffer[rcv_file_num].play_data, 0, PLAY_LENGTH); 
              memcpy(my_play_buffer[rcv_file_num].play_data, f_buf, PLAY_LENGTH); 
              if (share_array_rcv[rcv_file_num]==1) 
                { 
                  pr1(hwndDlg, "**** error: share_array_rcv[rcv_file_num]==1\r\n"); 
                  SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_STOP, (LPARAM) 0); 
                } 
              else 
                { 
                  share_array_rcv[rcv_file_num]=1; 
                  rcv_file_num++; 
                  if(rcv_file_num==PLAY_BUF_LEN) 
                  rcv_file_num=0; 
                } 
              } 
}