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

📄 tftpserver.c

📁 tftpServer 是支持tftp(trivial file transport protocol)协议的服务器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (errno || !req->file)		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(2);			strcpy(req->serverError.errormessage, "Invalid Path or No Access");			logMess_2(req, 1);			req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);						cleanReq(req);			pthread_exit(NULL);		}	}	if (ntohs(req->datain.opcode) == 1)  //handle RRQ	{		//allocate memory for req->pkt.		errno = 0;		req->pkt = (struct packet *)malloc(req->blksize + 4);				if (errno || !req->pkt)		{			sprintf(logBuff,"Memory Error");			logMess(1);            req->attempt = 255;            			cleanReq(req);			pthread_exit(NULL);		}		if (ftell(req->file))			fseek(req->file, 0, SEEK_SET);        // send DATA(1)		errno = 0;		req->block = 1;		req->pkt->opcode = htons(3);		req->pkt->block = htons(req->block);		req->bytesRead = fread(&req->pkt->buffer, 1, req->blksize, req->file);		if (errno)		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(0);			sprintf(req->serverError.errormessage, "%s", strerror(errno));			logMess_2(req, 1);			req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);						cleanReq(req);			pthread_exit(NULL);		}				req->bytesSent = send(req->m_socket, (const char*)req->pkt, req->bytesRead + 4, 0);		req->fblock++;		if (errno)		{			sprintf(req->serverError.errormessage, "Communication Error");			logMess_2(req, 1);								cleanReq(req);			pthread_exit(NULL);	    }        //if it reaches the end of file, close file.		if (req->bytesRead != req->blksize)		{			fclose(req->file);			req->file = 0;		}				while (1)		{			//try to get response from client.			FD_ZERO(&req->readfds);			req->tv.tv_sec = req->interval;			req->tv.tv_usec = 0;			FD_SET(req->m_socket, &req->readfds);			select(req->m_socket + 1, &req->readfds, NULL, NULL, &req->tv);			if (FD_ISSET(req->m_socket, &req->readfds))			{			    //get response from client.				errno = 0;				req->bytesReceived = recv(req->m_socket, (char*) & (req->datain), sizeof(struct ack), 0);				if (errno)				{					sprintf(req->serverError.errormessage, "Communication Error");					logMess_2(req, 1);										cleanReq(req);					pthread_exit(NULL);				}			}			else				req->bytesReceived = 0;  //no client response available.			if (req->bytesReceived >= 4)			{				//the ACK frame is what we expected.				if (ntohs(req->datain.opcode) == 4)				{					if (ntohs(req->datain.block) == req->block)					{   //the block is what we expected.						req->block++;						req->attempt = 0;		                if (req->file)		                {		                	//if there are still datus to send, continue.		                	//read data from file and put it into req->pkt.		                	errno = 0;		                    req->pkt->opcode = htons(3);		                    req->pkt->block = htons(req->block);		                    req->bytesRead = fread(&req->pkt->buffer, 1, req->blksize, req->file);		                    		                    if (errno)		                    {			                    req->serverError.opcode = htons(5);			                    req->serverError.errorcode = htons(0);			                    sprintf(req->serverError.errormessage, "%s", strerror(errno));			                    logMess_2(req, 1);			                    req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);						                    cleanReq(req);			                    pthread_exit(NULL);		                    }				                    //send req->pkt.		                    req->bytesSent = send(req->m_socket, (const char*)req->pkt, req->bytesRead + 4, 0);		                    req->fblock++;		                    if (errno)		                    {			                    sprintf(req->serverError.errormessage, "Communication Error");			                    logMess_2(req, 1);								                    cleanReq(req);			                    pthread_exit(NULL);	                        }                            //if it reaches the end of file, close file.		                    if (req->bytesRead != req->blksize)		                    {			                    fclose(req->file);			                    req->file = 0;		                    }		                }		                else		                {		                    sprintf(logBuff, "Client %s:%u %s, %u Blocks Served", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->fblock);				            logMess(2);				            req->attempt = 255;				            break;		                }					}					else						continue;				}				else if (ntohs(req->datain.opcode) == 5)				{					sprintf(req->serverError.errormessage, "Client %s:%u, Error Code %i at Client, %s", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), ntohs(req->clientError.errorcode), req->clientError.errormessage);					logMess_2(req, 1);										cleanReq(req);					pthread_exit(NULL);				}				else				{					req->serverError.opcode = htons(5);					req->serverError.errorcode = htons(0);					strcpy(req->serverError.errormessage, "Unexpected Option Code");					logMess_2(req, 1);					req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);										cleanReq(req);					pthread_exit(NULL);				}			}			else if (req->attempt >= 3)			{				req->serverError.opcode = htons(5);				req->serverError.errorcode = htons(0);                strcpy(req->serverError.errormessage, "Timeout");                logMess_2(req, 1);				req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);								cleanReq(req);				pthread_exit(NULL);			}			else			{				//resend previous frame.				errno = 0;				req->bytesSent = send(req->m_socket, (const char*)req->pkt, req->bytesSent, 0);				req->attempt++;								if (errno)				{					sprintf(req->serverError.errormessage, "Communication Error");					logMess_2(req, 1);										cleanReq(req);					pthread_exit(NULL);				}            }		}	}	else if (ntohs(req->datain.opcode) == 2)   //handle WRQ	{		//send ACK(0) to client.		req->block = 0;		req->acout.opcode = htons(4);		req->acout.block = htons(req->block);		errno = 0;		req->bytesSent = send(req->m_socket, (const char*) & (req->acout), 4, 0);				if (errno)	    {		    sprintf(req->serverError.errormessage, "Communication Error");		    logMess_2(req, 1);				    cleanReq(req);		    pthread_exit(NULL);	    }				errno = 0;		req->pkt = (struct packet *)malloc(req->blksize + 4);		if (errno || !req->pkt)		{			sprintf(logBuff,"Memory Error");			logMess(1);                        req->attempt = 255;			cleanReq(req);			pthread_exit(NULL);		}		while (1)		{			//try to get response from client.			FD_ZERO(&req->readfds);			req->tv.tv_sec = req->interval;			req->tv.tv_usec = 0;			FD_SET(req->m_socket, &req->readfds);			select(req->m_socket + 1, &req->readfds, NULL, NULL, &req->tv);			if (FD_ISSET(req->m_socket, &req->readfds))			{			    //get response from client.				errno = 0;				req->bytesReceived = recv(req->m_socket, (char*)req->pkt, req->blksize + 4, 0);				if (errno)				{					sprintf(req->serverError.errormessage, "Communication Error");					logMess_2(req, 1);										cleanReq(req);					pthread_exit(NULL);				}			}			else				req->bytesReceived = 0;  //no client response available.			if (req->bytesReceived >= 4)			{				if (ntohs(req->pkt->opcode) == 3)				{					//the opcode(DATA) is what we expected.					if (ntohs(req->pkt->block) == req->block + 1)					{						//the block is what we expected, send ACK to client.						req->acout.opcode = htons(4);						req->acout.block = htons(req->block + 1);						req->block++;						errno = 0;						req->bytesSent = send(req->m_socket, (const char*)&req->acout, 4, 0);												if (errno )						{							sprintf(req->serverError.errormessage, "Communication Error");							logMess_2(req, 1);														cleanReq(req);							pthread_exit(NULL);						}						if (req->file && req->bytesReceived > 4)						{							errno = 0;							fwrite(&req->pkt->buffer, req->bytesReceived - 4, 1, req->file);							if (errno)							{								req->serverError.opcode = htons(5);								req->serverError.errorcode = htons(3);								strcpy(req->serverError.errormessage, "Disk full or allocation exceeded");								logMess_2(req, 1);								req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);																cleanReq(req);								pthread_exit(NULL);							}							else							{								req->fblock++;								req->attempt = 0;							}						}						if (req->bytesReceived - 4 < req->blksize)						{							fclose(req->file);							req->file = 0;														sprintf(logBuff, "Client %s:%u %s, %u Blocks Received", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->fblock);							logMess(2);							break;						}					}					else						continue;				}				else if (ntohs(req->pkt->opcode) == 5)				{					sprintf(logBuff, "Error Code %i at Client, %s", ntohs(req->clientError.errorcode), req->clientError.errormessage);					logMess(1);										cleanReq(req);					pthread_exit(NULL);				}				else				{					req->serverError.opcode = htons(5);					req->serverError.errorcode = htons(4);					strcpy(req->serverError.errormessage, "Unexpected Option Code");					logMess_2(req, 1);					req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);										cleanReq(req);					pthread_exit(NULL);				}			}			else if (req->attempt >= 3)			{				req->serverError.opcode = htons(5);				req->serverError.errorcode = htons(0);				strcpy(req->serverError.errormessage, "Timeout");				logMess_2(req, 1);				req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);								cleanReq(req);				pthread_exit(NULL);			}			else			{				errno = 0;				send(req->m_socket, (const char*)&req->acout, req->bytesSent, 0);				req->attempt++;				if (errno )				{					sprintf(req->serverError.errormessage, "Communication Error");					logMess_2(req, 1);										cleanReq(req);					pthread_exit(NULL);				}			}		}	}	cleanReq(req);	pthread_exit(NULL);}void cleanReq(struct request* req){printf("tid[%d] cleanReq executed .\n", req->threadId);	if (req->file)	{		fclose(req->file);		req->file = 0;    }	if (req->m_socket >= 0)	{		close(req->m_socket);		req->m_socket = 0;    }	if (req->pkt)	{		free(req->pkt);		req->pkt = 0;    }	free(req);	req = NULL;}

⌨️ 快捷键说明

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