我需要有关如何为使用 UDP 的基本文件传输程序设计消息格式、窗口数据结构和确认以及错误检查的帮助。我正在寻找算法或一些基本的源代码来帮助我完成作业。
这是我之前做的 TCP 的服务器。我需要窗口结构和重传、要丢弃的数据包编号、损坏的数据包编号等配置。
#include "unp.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int Read(int,void*,size_t,int,SA*,socklen_t);
void Write(int,void*,int,int,SA*,socklen_t);
int packetSend(int ,SA* ,socklen_t,int );
int recieveAck(int ,SA* ,socklen_t,int );
const long packetSize = 1024;
struct Header
{
int seqNum,ackNum;
char da[32];
char sa[32];
};
struct Seg
{
Header head;
char data[packetSize];
};
Seg *buffer;
int nOfPackets;
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
}
void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char *mesg;
int size,bytesRead;
while(1){
len = clilen;
mesg= new char [MAXLINE];
n=Read(sockfd, mesg, MAXLINE, 0, pcliaddr, len);
cout<<"File Name "<<mesg<<endl;
int sockfd2;
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9878);
inet_pton(AF_INET,"127.0.0.1"/*argv[1]*/, &servaddr.sin_addr);
sockfd2 = socket(AF_INET, SOCK_DGRAM, 0);
//dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
socklen_t servlen = sizeof(servaddr);
// pcliaddr= &cliaddr;
ifstream infile (mesg,ifstream::binary);
infile.seekg(0,ifstream::end);
size=infile.tellg();
infile.seekg(0);
nOfPackets = (size/packetSize)+1;
cout<<"File Size: "<<size<<endl;
cout<<"Number of Packets: "<<nOfPackets<<endl;
Write(sockfd2,&size,4,0,(SA *) &servaddr,servlen );
buffer = new Seg [nOfPackets];
bytesRead = 0;
int count = 0;
while(bytesRead!=size)
{
if(size-bytesRead<packetSize)
{
int remaining = size-bytesRead;
buffer[count].head.seqNum = count;
infile.read (buffer[count].data,remaining);
bytesRead += remaining;
}
else
{
buffer[count].head.seqNum = count;
infile.read (buffer[count].data,packetSize);
bytesRead += packetSize;
count++;
}
}
packetSend (sockfd2,(SA*) &servaddr,servlen,0);
delete[] mesg;
infile.close();
}
}
void Write(int sockfd,void* sendline,int lent,int flg, SA* pcliaddr,socklen_t len)
{
sendto(sockfd,sendline, lent, 0, pcliaddr, len);
}
int Read(int sockfd,void* recvline,size_t lent,int flg,SA* pcliaddr,socklen_t len)
{
int n;
n = recvfrom(sockfd,recvline,lent,0, pcliaddr, &len);
return n;
}
int packetSend(int sockfd,SA* pcliaddr,socklen_t len,int i)
{
if(i==nOfPackets)
return i;
else
{
Seg *seg = new Seg;
seg = &(buffer[i]);
Write(sockfd,seg,sizeof(*seg),0,pcliaddr, len);
if(recieveAck(sockfd,pcliaddr,len,i)==i)
packetSend (sockfd,pcliaddr,len,++i);
else
packetSend (sockfd,pcliaddr,len,i);
}
}
int recieveAck(int sockfd ,SA* pcliaddr,socklen_t len,int num)
{
Header ack;
Read(sockfd, &ack, sizeof(ack), 0, pcliaddr, len);
if(ack.ackNum == num)
{
return ack.ackNum;
}
else return -1;
}