gpt4 book ai didi

c - 套接字程序-使用UDP可靠的数据传输

转载 作者:行者123 更新时间:2023-11-30 20:32:58 25 4
gpt4 key购买 nike

我已经用 C 编写了可靠数据传输的代码。这里客户端以 1024 字节的 block 将文件发送到服务器。服务器将收到的数据包写入另一个文件中。

该程序适用于字符串文件/二进制数据文件。但是当我尝试复制图像文件时出现了问题。当我尝试传输 .jpg 文件时,没有编译错误或运行时错误。但是当我尝试打开目标文件时,它说:“无法打开图像文件”,“解释 jpeg 文件时出错”“在状态 201 下不正确调用 jpeg 库”。

任何人都可以查看代码并提出任何解决方案吗?

这是我的客户端代码

#include<stdio.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<arpa/inet.h>

char *itoa(long i,char *s,int dummy_radix)
{
sprintf(s,"%ld",i);
return s;
}

int main(int argc, int *argv[])
{
int sock,length,n;
struct sockaddr_in server,from;
struct hostent *hp;
long int packets =0;
unsigned char buff[1024] = {0};

// checking if hostname and the port address is provided //
if(argc!=3)
{
printf("insufficient arguments\n");
exit(1);
}

//create a socket//
sock = socket(AF_INET,SOCK_DGRAM,0);

if(sock<0)
{
printf("error in opening socket\n");
return 1;
}

//to get the hostname of the system or the machine//
hp= gethostbyname(argv[1]);

if(hp==0)
{
printf("Unknown host\n");
return 1;
}
//build the server's IP address //
bzero((char *)&server,sizeof(server));
bcopy((char*)hp->h_addr,(char *)&server.sin_addr,hp->h_length);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
length = sizeof(server);

/*open the file that we wish to transfer*/
FILE *fp = fopen("landscape.jpeg","rb");
if(fp==NULL)
{
printf("file open error");
return 1;
}
fseek(fp,0,SEEK_END); //if exists read the size of the file
size_t file_size = ftell(fp);
fseek(fp,0,SEEK_SET);

printf("size of the file is %d\n", file_size);

/*find the number of packets*/
packets = (file_size/1024)+1 ;

/*send the number of packets to the server*/
itoa(packets,buff,10);
n = sendto(sock,buff,strlen(buff),0,(struct sockaddr *)&server,sizeof(struct sockaddr));
if(n<0)
{
printf("error in sending message to the serveR");
return 1;
}

/*Read data from file and send it*/
int packetNum = 0;
while(1)
{
/*First read file in chunks of 1024 bytes */
int nread = fread(buff,1,1024,fp);
//printf("Bytes read %d\n",nread);

/*if read was success ,send data*/
if(nread>0)
{
//printf("data sent now is %s\n",buff);
n = sendto(sock,buff,strlen(buff),0,(struct sockaddr *)&server,sizeof(struct sockaddr));
printf("Sending %d, numBytes sent: %d\n", packetNum, n);
packetNum++;
if(n<0)
{
printf("error in sending message to the server");
fclose(fp);
return 1;
}
}

/*There is something tricky going on with the read..
* Either there was error ,or we reached end of file.
*/
if(nread<1024)
{
if(feof(fp))
printf("End of file\n");

if(ferror(fp))
printf("Error reading\n");
break;
}
}
close(sock);
fclose(fp);

return 0;
}

这是我的服务器代码

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<arpa/inet.h>

int main(int argc, char *argv[])
{
int sock,length,fromlen,n;
struct sockaddr_in server;
struct sockaddr_in from;
char buf[1024];
char file_buf[1024];
int packets = 0;
int received = 0;
FILE *newfp;
newfp = fopen("output.jpeg","wb");
if(newfp==NULL)
{
printf("error opening the file\n");
return 1;
}
if(argc<2)
{
fprintf(stderr, "no port number specified\n");
exit(0);
}
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
{
printf("error in opening socket\n");
return 1;
}
length = sizeof(server);
bzero(&server,length);
server.sin_family= AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(atoi(argv[1]));
if(bind(sock,(struct sockaddr*)&server,length)<0)
{
printf("cannot bind\n");
return 1;
}
fromlen = sizeof(struct sockaddr_in);
n = recvfrom(sock,buf,1024,0,(struct sockaddr *)&from,&fromlen);
if(n<0)
{
printf("recvfrom error\n");
return 1;
}

packets = atoi(buf);
printf("Num packets expected: %d\n", packets);

while(received<packets)
{
n = recvfrom(sock,buf,sizeof (buf),0,(struct sockaddr *)&from,&fromlen);

//printf ("%d\n", n);
printf("Packet num %d, numBytes received: %d\n", received, n);

if(n<0)
{
printf("recvfrom error\n");
return 1;
}
//printf("%s",buf);
if((fwrite(buf,1,n,newfp)) < n)
{
printf("error in writing to the file\n");
return 1;
}
received++;
}
printf("Finished\n");
fclose(newfp);
return 0;
}

最佳答案

  1. 您假设 fread()以空值终止缓冲区。事实并非如此。
  2. 您假设数据不包含其他空值:它可以。
  3. 您应该使用nread而不是strlen(buffer)作为发送文件数据时的计数参数。
  4. 文件结尾的正确测试不是 nread < 1024 ,这可能随时发生:它是 nread == 0 .
  5. 您没有处理无序的数据包、丢失或重复的数据包。事实上,这段代码根本不可靠。您需要数据包中的序列号,这些序列号在将数据写入文件时会被删除;您需要针对丢失数据包的 ACK 或 NACK 机制;你需要一个忽略重复的机制; ...

你才刚刚开始。

关于c - 套接字程序-使用UDP可靠的数据传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46554394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com