// File: BelfordZ[P]SimpleFileServer/Client.cpp
// Function: Client::connect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void Client::connect(const std::string& fileName) {

   //
   // Create sockets to connect to the Server on the dispatch ports
   //
   
   sktOut = new Socket();
   sktOut->create();
   if(!sktOut->connect(SERVER_NAME, CLIENT_DISPATCH_PORT)) {
      std::cout << "ERROR: Could not connect to output dispatch port " << CLIENT_DISPATCH_PORT << std::endl;
      exit(-1);
   }
  
   sktIn = new Socket();
   sktIn->create();

   if(!sktIn->connect(SERVER_NAME, SERVER_DISPATCH_PORT)) {
      std::cout << "ERROR: Could not connect to input dispatch port " << SERVER_DISPATCH_PORT << std::endl;
      exit(-1);
   }

   std::string outFileName = "client_" + to_string<__pid_t>(getpid()) + "_" + fileName;
   outFile = new std::ofstream(outFileName.c_str());
   
   //
   // Send CLIENT_HELLO on dispatch port
   //
   
   Frame clientHello(CLIENT_HELLO, fileName, to_string<__pid_t>(getpid()));
   std::cout << "Sending CLIENT_HELLO... ";
   send_frame(clientHello);
   std::cout << "Done!" << std::endl;

   //
   // Process the SERVER_HELLO to determine the transfer port to use
   //
   
   std::cout << "Waiting for SERVER_HELLO... ";
   Frame serverHello = receive_frame();
   int serverPortIn = std::atoi(serverHello.get_data().c_str()); // Get the transfer input port
   int serverPortOut = serverPortIn + 1;
   std::cout << "Done!" << std::endl;
   std::cout << "Handshake complete, dispatched to port " << serverPortIn << std::endl;
   sleep(1);

   //
   // Delete dispatch sockets, we don't need them anymore
   //
   
   delete sktIn;
   delete sktOut;

   //
   // Create new sockets in order to connect to the transfer ports
   //
   
   sktIn = new Socket();
   sktIn->create();

   if(!sktIn->connect(SERVER_NAME, serverPortIn)) {
      std::cout << "ERROR: Could not connect to input port " << serverPortIn << " specified by server"
		<< std::endl;
      exit(-1);
   }

   sktOut = new Socket();
   sktOut->create();
   if(!sktOut->connect(SERVER_NAME, serverPortOut)) {
      std::cout << "ERROR: Could not connect to output port " << serverPortOut << " specified by server"
		<< std::endl;
      exit(-1);
   }

   //
   // Assuming everything went correctly, we should be connected to the server!
   // Send ACK and start transferring our file!
   //
   
   Frame ackFrame(ACK, "FILE PLZ");
   send_frame(ackFrame);
   std::cout << "--------------------[ BEGIN TRANSMISSION ]--------------------" << std::endl;
	
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3b0, %rsp            # imm = 0x3B0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x2a0(%rbp)
movl $0x20, %edi
callq 0x3290
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x298(%rbp)
callq 0x7460
jmp 0x3ecc
movq -0x2a0(%rbp), %rax
movq -0x298(%rbp), %rcx
movq %rcx, 0x40(%rax)
movq 0x40(%rax), %rdi
callq 0x7760
movq -0x2a0(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x2b8(%rbp)
leaq 0x83d8(%rip), %rsi      # 0xc2d8
leaq -0x40(%rbp), %rdi
movq %rdi, -0x2b0(%rbp)
callq 0x3120
movq -0x2b8(%rbp), %rdi
movq -0x2b0(%rbp), %rsi
movl $0x9c41, %edx           # imm = 0x9C41
callq 0x7b40
movb %al, -0x2a1(%rbp)
jmp 0x3f30
movb -0x2a1(%rbp), %al
xorb $-0x1, %al
movb %al, -0x2b9(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3518
movb -0x2b9(%rbp), %al
testb $0x1, %al
jne 0x3f53
jmp 0x3fc8
movq 0x8076(%rip), %rdi      # 0xbfd0
leaq 0x40ea(%rip), %rsi      # 0x804b
callq 0x3280
movq %rax, %rdi
movl $0x9c41, %esi           # imm = 0x9C41
callq 0x3450
movq %rax, %rdi
movq 0x803b(%rip), %rsi      # 0xbfb8
callq 0x32d0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3350
movq -0x298(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x20, %esi
callq 0x32a0
jmp 0x48b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3518
jmp 0x48b3
movl $0x20, %edi
callq 0x3290
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x2c8(%rbp)
callq 0x7460
jmp 0x3fe6
movq -0x2a0(%rbp), %rax
movq -0x2c8(%rbp), %rcx
movq %rcx, 0x38(%rax)
movq 0x38(%rax), %rdi
callq 0x7760
movq -0x2a0(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x2e0(%rbp)
leaq 0x82be(%rip), %rsi      # 0xc2d8
leaq -0x60(%rbp), %rdi
movq %rdi, -0x2d8(%rbp)
callq 0x3120
movq -0x2e0(%rbp), %rdi
movq -0x2d8(%rbp), %rsi
movl $0x9c40, %edx           # imm = 0x9C40
callq 0x7b40
movb %al, -0x2c9(%rbp)
jmp 0x404a
movb -0x2c9(%rbp), %al
xorb $-0x1, %al
movb %al, -0x2e1(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x3518
movb -0x2e1(%rbp), %al
testb $0x1, %al
jne 0x406d
jmp 0x40e2
movq 0x7f5c(%rip), %rdi      # 0xbfd0
leaq 0x4002(%rip), %rsi      # 0x807d
callq 0x3280
movq %rax, %rdi
movl $0x9c40, %esi           # imm = 0x9C40
callq 0x3450
movq %rax, %rdi
movq 0x7f21(%rip), %rsi      # 0xbfb8
callq 0x32d0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3350
movq -0x2c8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x20, %esi
callq 0x32a0
jmp 0x48b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x3518
jmp 0x48b3
callq 0x33f0
movl %eax, -0xe4(%rbp)
leaq -0xe0(%rbp), %rdi
movq %rdi, -0x2f0(%rbp)
leaq -0xe4(%rbp), %rsi
callq 0x53d0
movq -0x2f0(%rbp), %rdx
leaq 0x3f99(%rip), %rsi      # 0x80ae
leaq -0xc0(%rbp), %rdi
callq 0x5380
jmp 0x4123
leaq 0x3f8a(%rip), %rdx      # 0x80b4
leaq -0xa0(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x5330
jmp 0x413f
movq -0x10(%rbp), %rdx
leaq -0x80(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x52e0
jmp 0x4155
leaq -0xa0(%rbp), %rdi
callq 0x3518
leaq -0xc0(%rbp), %rdi
callq 0x3518
leaq -0xe0(%rbp), %rdi
callq 0x3518
movl $0x200, %edi            # imm = 0x200
callq 0x3290
movq %rax, -0x2f8(%rbp)
jmp 0x418c
leaq -0x80(%rbp), %rdi
callq 0x3110
movq -0x2f8(%rbp), %rdi
movq %rax, %rsi
movl $0x10, %edx
callq 0x3300
jmp 0x41ab
movq -0x2a0(%rbp), %rax
movq -0x2f8(%rbp), %rcx
movq %rcx, 0x30(%rax)
movl $0x0, -0x134(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x300(%rbp)
callq 0x33f0
movl %eax, -0x15c(%rbp)
leaq -0x158(%rbp), %rdi
leaq -0x15c(%rbp), %rsi
callq 0x53d0
jmp 0x41f2
movq -0x300(%rbp), %rdx
leaq -0x130(%rbp), %rdi
leaq -0x134(%rbp), %rsi
leaq -0x158(%rbp), %rcx
callq 0x5820
jmp 0x4215
leaq -0x158(%rbp), %rdi
callq 0x3518
movq 0x7da8(%rip), %rdi      # 0xbfd0
leaq 0x3e87(%rip), %rsi      # 0x80b6
callq 0x3280
jmp 0x4236
movq -0x2a0(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x48c0
jmp 0x424b
movq 0x7d7e(%rip), %rdi      # 0xbfd0
leaq 0x4167(%rip), %rsi      # 0x83c0
callq 0x3280
movq %rax, -0x308(%rbp)
jmp 0x4267
movq -0x308(%rbp), %rdi
movq 0x7d43(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x427c
movq 0x7d4d(%rip), %rdi      # 0xbfd0
leaq 0x3e45(%rip), %rsi      # 0x80cf
callq 0x3280
jmp 0x4291
movq -0x2a0(%rbp), %rsi
leaq -0x1a8(%rbp), %rdi
callq 0x4930
jmp 0x42a6
leaq -0x1d0(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x5470
jmp 0x42bb
leaq -0x1d0(%rbp), %rdi
movq %rdi, -0x320(%rbp)
callq 0x3110
movq %rax, %rdi
callq 0x3420
movq -0x320(%rbp), %rdi
movl %eax, -0x314(%rbp)
callq 0x3518
movl -0x314(%rbp), %eax
movl %eax, -0x1ac(%rbp)
movl -0x1ac(%rbp), %eax
incl %eax
movl %eax, -0x1d4(%rbp)
movq 0x7cc7(%rip), %rdi      # 0xbfd0
leaq 0x40b0(%rip), %rsi      # 0x83c0
callq 0x3280
movq %rax, -0x310(%rbp)
jmp 0x431e
movq -0x310(%rbp), %rdi
movq 0x7c8c(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x4333
movq 0x7c96(%rip), %rdi      # 0xbfd0
leaq 0x3dab(%rip), %rsi      # 0x80ec
callq 0x3280
movq %rax, -0x328(%rbp)
jmp 0x434f
movq -0x328(%rbp), %rdi
movl -0x1ac(%rbp), %esi
callq 0x3450
movq %rax, -0x330(%rbp)
jmp 0x436a
movq -0x330(%rbp), %rdi
movq 0x7c40(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x437f
movl $0x1, %edi
callq 0x31f0
jmp 0x438b
movq -0x2a0(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x338(%rbp)
cmpq $0x0, %rax
je 0x43b0
movq -0x338(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x2a0(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x340(%rbp)
cmpq $0x0, %rax
je 0x43d5
movq -0x340(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movl $0x20, %edi
callq 0x3290
movq %rax, -0x348(%rbp)
jmp 0x43e8
movq -0x348(%rbp), %rdi
callq 0x7460
jmp 0x43f6
movq -0x2a0(%rbp), %rax
movq -0x348(%rbp), %rcx
movq %rcx, 0x38(%rax)
movq 0x38(%rax), %rdi
callq 0x7760
jmp 0x4413
movq -0x2a0(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x350(%rbp)
leaq 0x7eac(%rip), %rsi      # 0xc2d8
leaq -0x1f8(%rbp), %rdi
callq 0x3120
jmp 0x443a
movq -0x350(%rbp), %rdi
movl -0x1ac(%rbp), %edx
leaq -0x1f8(%rbp), %rsi
callq 0x7b40
movb %al, -0x351(%rbp)
jmp 0x445b
movb -0x351(%rbp), %al
xorb $-0x1, %al
movb %al, -0x352(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x3518
movb -0x352(%rbp), %al
testb $0x1, %al
jne 0x4484
jmp 0x45f8
movq 0x7b45(%rip), %rdi      # 0xbfd0
leaq 0x3c82(%rip), %rsi      # 0x8114
callq 0x3280
movq %rax, -0x360(%rbp)
jmp 0x44a0
movq -0x360(%rbp), %rdi
movl -0x1ac(%rbp), %esi
callq 0x3450
movq %rax, -0x368(%rbp)
jmp 0x44bb
movq -0x368(%rbp), %rdi
leaq 0x3c73(%rip), %rsi      # 0x813c
callq 0x3280
movq %rax, -0x370(%rbp)
jmp 0x44d7
movq -0x370(%rbp), %rdi
movq 0x7ad3(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x44ec
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3350
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x4536
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x452a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x3518
leaq -0xc0(%rbp), %rdi
callq 0x3518
leaq -0xe0(%rbp), %rdi
callq 0x3518
jmp 0x48b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x48aa
movq -0x2f8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x200, %esi            # imm = 0x200
callq 0x32a0
jmp 0x48aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x3518
jmp 0x48aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x489e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x4892
movq -0x348(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x20, %esi
callq 0x32a0
jmp 0x4892
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x3518
jmp 0x4892
movl $0x20, %edi
callq 0x3290
movq %rax, -0x378(%rbp)
jmp 0x460b
movq -0x378(%rbp), %rdi
callq 0x7460
jmp 0x4619
movq -0x2a0(%rbp), %rax
movq -0x378(%rbp), %rcx
movq %rcx, 0x40(%rax)
movq 0x40(%rax), %rdi
callq 0x7760
jmp 0x4636
movq -0x2a0(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x380(%rbp)
leaq 0x7c89(%rip), %rsi      # 0xc2d8
leaq -0x218(%rbp), %rdi
callq 0x3120
jmp 0x465d
movq -0x380(%rbp), %rdi
movl -0x1d4(%rbp), %edx
leaq -0x218(%rbp), %rsi
callq 0x7b40
movb %al, -0x381(%rbp)
jmp 0x467e
movb -0x381(%rbp), %al
xorb $-0x1, %al
movb %al, -0x382(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x3518
movb -0x382(%rbp), %al
testb $0x1, %al
jne 0x46a7
jmp 0x4758
movq 0x7922(%rip), %rdi      # 0xbfd0
leaq 0x3a9c(%rip), %rsi      # 0x8151
callq 0x3280
movq %rax, -0x390(%rbp)
jmp 0x46c3
movq -0x390(%rbp), %rdi
movl -0x1d4(%rbp), %esi
callq 0x3450
movq %rax, -0x398(%rbp)
jmp 0x46de
movq -0x398(%rbp), %rdi
leaq 0x3a50(%rip), %rsi      # 0x813c
callq 0x3280
movq %rax, -0x3a0(%rbp)
jmp 0x46fa
movq -0x3a0(%rbp), %rdi
movq 0x78b0(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x470f
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3350
movq -0x378(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x20, %esi
callq 0x32a0
jmp 0x4892
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x3518
jmp 0x4892
movl $0x5, -0x264(%rbp)
leaq -0x289(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0x3470
movq -0x3a8(%rbp), %rdx
leaq 0x39f7(%rip), %rsi      # 0x817a
leaq -0x288(%rbp), %rdi
callq 0x3aa0
jmp 0x4791
leaq -0x260(%rbp), %rdi
leaq -0x264(%rbp), %rsi
leaq -0x288(%rbp), %rdx
movl $0x1, %ecx
callq 0x5530
jmp 0x47b2
leaq -0x288(%rbp), %rdi
callq 0x3518
leaq -0x289(%rbp), %rdi
callq 0x32f0
movq -0x2a0(%rbp), %rdi
leaq -0x260(%rbp), %rsi
callq 0x48c0
jmp 0x47df
movq 0x77ea(%rip), %rdi      # 0xbfd0
leaq 0x3996(%rip), %rsi      # 0x8183
callq 0x3280
movq %rax, -0x3b0(%rbp)
jmp 0x47fb
movq -0x3b0(%rbp), %rdi
movq 0x77af(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x4810
leaq -0x260(%rbp), %rdi
callq 0x54a0
leaq -0x1a8(%rbp), %rdi
callq 0x54a0
leaq -0x130(%rbp), %rdi
callq 0x54a0
leaq -0x80(%rbp), %rdi
callq 0x3518
addq $0x3b0, %rsp            # imm = 0x3B0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x486c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x3518
leaq -0x289(%rbp), %rdi
callq 0x32f0
jmp 0x4892
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x54a0
leaq -0x1a8(%rbp), %rdi
callq 0x54a0
leaq -0x130(%rbp), %rdi
callq 0x54a0
leaq -0x80(%rbp), %rdi
callq 0x3518
movq -0x18(%rbp), %rdi
callq 0x3460
nopl (%rax)