0 Replies - 4375 Views - Last Post: 23 November 2011 - 12:40 PM Rate Topic: -----

#1 Massaslayer  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 07-July 07

XChat ACK Fails when sending files

Posted 23 November 2011 - 12:40 PM

Hello!

I'm making an IRC Client with DCC Capabilities.

The DCC Specifications say this about receiving files:

The recipient should acknowledge each packet by transmitting
the total number of bytes received as an unsigned, 4 byte
integer in network byte order.


In do this with the following code:
typedef unsigned int guint32;
guint32 pos = htonl (count & 0xffffffff); 
send(sockfd,(char*) &pos,4,0); 


This is the same code that is in the XChat source code.

Now this code works fine with the xchat client itself.

But those 3 lines of code make my own client fail in sending files to another instance of my client.
When I include those 3 lines and I run 2 instances of my program and then try to send a file to each other, the program sends 10 MB of the file and then just stops.

This is my send code:
void listenSocket (void *arg,void *inputUser,void *inputFileName,void *inputFileLoc)
{
	struct sockaddr_storage their_addr;
	struct addrinfo hints, *servinfo;
	struct in_addr addr;
	socklen_t addr_size;

	int len, bytes_sent, bytes_received, fdmax, new_fd, nbytes, j, i,myRandPort=0;
	int sockfdIRCSocket = (int)arg,	sockfd ,bindfd , listenfd;
	unsigned long long int countSentBytes=0;

	char *sendToUser = (char*)inputUser, *fileName = (char*)inputFileName, *fileLoc = (char*)inputFileLoc;
	char strSizeFile[50], buffer[5120], hostip[30], read[500], sendDCC[500], decResult[50], hostname[80], *pch;
	char buf[500], remoteIP[INET6_ADDRSTRLEN], MYPORT[6]="\0",bufferke[4];  

	long sizeFile;

	bool bolSendFile = false;

	fd_set master;    // master file descriptor list
	fd_set read_fds;

	strSizeFile[0] = '\0';
	decResult[0]= '\0';
	hostip[0]= '\0';

	srand(time(NULL));
	myRandPort=getRand(49152,65535);
	sprintf(MYPORT,"%d",myRandPort);

	//Socket Stuff
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
		Log("WSAStartup","WSAStartup failed");
		closesocket(1);
	}

	//File thats needs to be sended
	FILE *fp;
	//Read + Open File
	if((fp = fopen(fileLoc, "rb+"))==NULL) {
		printf(":Cannot open file, please pick another.\n");	 
		Log("DCC File Send","Cannot open file, please pick another.");	 
		return;
	}

	//Get Filesize
	fseek(fp, 0,SEEK_END);
	sizeFile = ftell(fp);
	ltoa(sizeFile,strSizeFile,10);
	fseek(fp, 0,SEEK_SET);

	//GET IP
	if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR) {
		Log("DCC Send Host","No Host Found");
	}

	struct hostent *phe = gethostbyname(hostname);
	memcpy(&addr, phe->h_addr_list[1], sizeof(struct in_addr));
	sprintf(hostip,"%s",inet_ntoa(addr));

	//Convert IP to Decimal notation
	sprintf(decResult,"%u", addr);
	sprintf(decResult,"%u", htonl(atoi(decResult)));

	// \001DCC SEND test.txt <decimal> 9999 70\001
	sendDCC[0] = '\0';     
	strcat(sendDCC,"PRIVMSG ");
	strcat(sendDCC, sendToUser);
	strcat(sendDCC," :\001DCC SEND ");
	strcat(sendDCC, fileName);
	strcat(sendDCC," ");
	strcat(sendDCC, decResult);
	strcat(sendDCC," ");
	strcat(sendDCC, MYPORT);
	strcat(sendDCC, " ");
	strcat(sendDCC, strSizeFile);
	strcat(sendDCC, "\001\n");

	//Socket Stuff
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever
	hints.ai_socktype = SOCK_STREAM; //TCP
	hints.ai_flags = AI_PASSIVE;     // fill in my IP for me

	//AddrInfo
	getaddrinfo(hostip,MYPORT, &hints, &servinfo);

	//Create a socket
	sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
	if(sockfd > 0)
	{
		//printf("\n:Socket(%i): OK\n\n",sockfd);
		Log("DCC Send Create Socket","Sockted created");
	}
	else
	{
		//wprintf(L"### Bind failed with error: %ld\n\n", WSAGetLastError());
		Log("DCC Send Create Socket","Sockted failed");
	}

	//Bind
	bindfd = bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);	
	if(bindfd == 0)
	{
		//printf(":Bind: OK\n\n",bindfd);
		Log("DCC Send Bind","Bind ok");
	}
	else
	{
		//wprintf(L"### Bind failed with error: %ld\n\n", WSAGetLastError());
		Log("DCC Send Bind","Bind failed");
	}

	//Listen
	for(;;)/>{

		listenfd = listen(sockfd, 10);
		if(listenfd == 0)
		{
			//printf(":Listening on port %s...\n\n",MYPORT);
			Log("Port listening",MYPORT);
		}
		else
		{
			//wprintf(L"### Listen failed with error: %ld\n\n", WSAGetLastError());
			Log("DCC Send Listen","Listen Failed");
		}

		FD_ZERO(&master);    
		FD_ZERO(&read_fds);
		FD_SET(sockfd, &master);
		fdmax = sockfd; 

		//sendToServer("PRIVMSG bigvince :\001DCC SEND test.txt 127.0.0.1 9999 70\001\n",(void *)sockfdIRCSocket);
		sendToServer(sendDCC,(void *)sockfdIRCSocket);
		int bytes_rex = 0;
		// main loop
		for(;;)/> {
			read_fds = master; // copy it
			if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
				//wprintf(L"### Select failed with error: %ld\n\n", WSAGetLastError());
				Log("DCC Send Select","Select failed");
				closesocket(4);
			}

			// run through the existing connections looking for data to read
			for(i = 0; i <= fdmax; i++) {
				if (FD_ISSET(i, &read_fds)) { // we got one!!
					if (i == sockfd) {

						// handle new connections
						addr_size = sizeof their_addr;
						new_fd = accept(sockfd,(struct sockaddr *)&their_addr,&addr_size);
						//printf("accept");

						if (new_fd == -1) {
							//wprintf(L"### Accept failed with error: %ld\n\n", WSAGetLastError());
							Log("DCC Send Accept","Accept failed");
						} 
						else 
						{
							Log("DCC Send Accept","Accept all good");

							FD_SET(new_fd, &master); // add to master set
							if (new_fd > fdmax) 
							{    // keep track of the max
								fdmax = new_fd;
							}

							//printf(":New connection from %s on socket %d\n\n", inet_ntop(their_addr.ss_family,&their_addr,remoteIP, INET6_ADDRSTRLEN),new_fd);
							Log("DCC Send New Connection", (char *)inet_ntop(their_addr.ss_family,&their_addr,remoteIP, INET6_ADDRSTRLEN));

							if (atoi(strSizeFile)<sizeof(buffer))
							{
								//Read file into buffer
								len = fread(&buffer,atoi(strSizeFile),1,fp);

								//Send buffer into network
								bytes_sent = send(new_fd, buffer, atoi(strSizeFile), 0);
								if (bytes_sent > 0)
								{
									printf("\n:>Sending file\n");
								}
								else if (bytes_sent == -1)
								{
									wprintf(L"### Send failed with error: %ld\n\n", WSAGetLastError());
									//Log("DCC Send Filebytes","Send failed");
									fclose(fp);
									return;
								}
							}
							else
							{ 
								do {
									//Read file into buffer
									fread(&buffer,sizeof(buffer),1,fp);

									//Send buffer into network
									bytes_sent = send(new_fd, buffer, sizeof(buffer), 0);
									if (bytes_sent > 0)
									{
											countSentBytes = countSentBytes + bytes_sent;
											if (bolSendFile == false)
											{
												printf("\n:>Sending file\n");
												bolSendFile = true;
											}
											printf(".");
									}
									else if (bytes_sent == -1)
									{
										wprintf(L"### Send failed with error: %ld\n\n", WSAGetLastError());
										//Log("DCC Send Filebytes","Send failed");
										fclose(fp);
										return;
									}
									else
									{
										printf("lala");
									}
								 
								}while(countSentBytes < atoi(strSizeFile));	 
							}
							if(countSentBytes = atoi(strSizeFile) )
							{
								printf("\n:>File transfer complete \n\n");
								bolSendFile = false;
							}
							fclose(fp);
						}
					}
				}
			}
		}
	}
}



And my Receive Code:

	struct sockaddr_storage their_addr;
	struct addrinfo hints, *servinfo, *p;
	struct in_addr addr;
	socklen_t addr_size;

	int  sockfd ,bindfd , listenfd;
	char buffer[1024], filePath[50];
	char s[INET6_ADDRSTRLEN], *dotted_quad;
	int numbytes=0;
	unsigned long long int count =0;
	bool bolRecvFile=false;

	FILE *fp;

	//File Location
	filePath[0] = '\0';
	strcat(filePath,"C:\\");
	strcat(filePath,file);
	strcat(filePath,"\0");

	//Socket Stuff
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
		Log("WSAStartup","WSAStartup failed");
		closesocket(1);
	}

	//Socket Stuff
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever
	hints.ai_socktype = SOCK_STREAM; //TCP
	hints.ai_flags = AI_PASSIVE;     // fill in my IP for me

	//Convert Decimal Notation to Dotted Decimal Notation
	unsigned long numeric_ip = (unsigned) strtoul(ip,NULL,10);
	numeric_ip = htonl(numeric_ip);  // flip the byte order
	memcpy(&addr, &numeric_ip, sizeof(numeric_ip));
	dotted_quad = inet_ntoa(addr);

	getaddrinfo(dotted_quad, port, &hints, &servinfo);

	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {
			//wprintf(L"### Socket failed with error: %ld\n\n", WSAGetLastError());
			Log("Socket","Sockted failed with error");
		}

		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			//wprintf(L"\n### Connect failed with error: %ld\n\n", WSAGetLastError());
			Log("Connect","Connect failed with error");
			closesocket(sockfd);
			continue;
		}
		break;
	}

	if (p == NULL) {
		printf("Failed to connect\n");
	}

	if((fp=fopen(filePath, "wb"))==NULL) {
		printf(":Cannot open file, please pick another.\n");	 
		Log("DCC File Receive","Cannot open file, please pick another.");	 
		return;
	}

	int bytes_sent=0;
	do {
		//Receiving From Socket
		numbytes = recv(sockfd, buffer, sizeof(buffer), 0);

		if(numbytes>4)
		{
			//Counting Bytes Received
			count = count + numbytes;
			if (bolRecvFile == false)
			{
				printf("\n:>Receiving File\n", file);
				bolRecvFile = true;
			}

			//Writing to file
			fwrite(buffer, numbytes, 1, fp);
			//printf("\n\nCount: %d Filesize: %d",count,filesize);

			//Sending ACK's
			typedef unsigned int guint32;
		 
			guint32 pos = htonl (count & 0xffffffff); 
			send(sockfd,(char*) &pos,4,0); 
		 

		}
	}while(count < filesize);
	if (count = filesize)
	{
		printf("\n:>Receiving File Completed\n\n",file);
		shutdown(sockfd,2);
		closesocket(sockfd);
		fclose(fp);
	}
	else
	{
		printf("\n:>Receiving File Failed\n\n");
	}







Much thanks to anyone who can help me, this is the last thing that needs to work then it's 100% finished!

Is This A Good Question/Topic? 0
  • +

Page 1 of 1