使用raspberry pi和windows通过C中的套接字发送图像(JPG)

使用raspberry pi和windows通过C中的套接字发送图像(JPG),c,C,我正在编写一个C程序,以便能够使用TCP/IP套接字在raspberry pi和windows pc计算机之间(从服务器raspberry pi到客户端pc)连续传输图像文件,但在发送第1017次后似乎出现错误,服务器通过声明分段错误退出,我的意思是在循环中,当我打算将映像文件发送到我的客户机2000次时,服务器在1017映像上退出 服务器端 #include<stdio.h> #include<string.h> #include<sys/socket.h>

我正在编写一个C程序,以便能够使用TCP/IP套接字在raspberry pi和windows pc计算机之间(从服务器raspberry pi到客户端pc)连续传输图像文件,但在发送第1017次后似乎出现错误,服务器通过声明分段错误退出,我的意思是在循环中,当我打算将映像文件发送到我的客户机2000次时,服务器在1017映像上退出

服务器端

#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>   
#include<unistd.h>  
#include<iostream>
#include<fstream>
#include<errno.h>

using namespace std;

int send_image(int socket){

    FILE *picture;
    int size, read_size, stat, packet_index;
    char send_buffer[10240], read_buffer[256];
    packet_index = 1;

    picture = fopen("a.jpg", "r");
    printf("Getting Picture Size\n");   

    if(picture == NULL) {
        printf("Error Opening Image File"); 
    }

    fseek(picture, 0, SEEK_END);
    size = ftell(picture);
    fseek(picture, 0, SEEK_SET);
    printf("Total Picture size: %i\n",size);

    //Send Picture Size
    printf("Sending Picture Size\n");
    write(socket, (void *)&size, sizeof(int));

    //Send Picture as Byte Array
    printf("Sending Picture as Byte Array\n");

    do { //Read while we get errors that are due to signals.
        stat=read(socket, &read_buffer , 255);
        printf("Bytes read: %i\n",stat);
    } while (stat < 0);

    printf("Received data in socket\n");
    printf("Socket data: %c\n", read_buffer);

    while(!feof(picture)) {
        //while(packet_index = 1){
        //Read from the file into our send buffer
        read_size = fread(send_buffer, 1, sizeof(send_buffer)-1, picture);

        //Send data through our socket 
        do{
            stat = write(socket, send_buffer, read_size);  
        }while (stat < 0);

        printf("Packet Number: %i\n",packet_index);
        printf("Packet Size Sent: %i\n",read_size);     
        printf(" \n");
        printf(" \n");

        packet_index++;  

        //Zero out our send buffer
        bzero(send_buffer, sizeof(send_buffer));
    }
}

int main(int argc , char *argv[])
{
    int socket_desc , new_socket , c, read_size,buffer = 0;
    struct sockaddr_in server , client;
    char *readin;

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8000 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        puts("bind failed");
        return 1;
    }

    puts("bind done");

    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);

    if((new_socket = accept(socket_desc, (struct sockaddr *)&client,       (socklen_t*)&c))){
        puts("Connection accepted");
     }

     fflush(stdout);

     if (new_socket<0)
     {
         perror("Accept Failed");
         return 1;
     }
     while(value<2000)
     {
         value =value+1;
         send_image(new_socket);
     }

     close(socket_desc);
     fflush(stdout);
     return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int发送_图像(int套接字){
文件*图片;
int size、read_size、stat、packet_索引;
字符发送缓冲区[10240],读取缓冲区[256];
数据包索引=1;
图片=fopen(“a.jpg”、“r”);
printf(“获取图片大小\n”);
if(picture==NULL){
printf(“打开图像文件时出错”);
}
fseek(图片,0,搜索结束);
尺寸=ftell(图片);
fseek(图片,0,搜索集);
printf(“图片总大小:%i\n”,大小);
//发送图片大小
printf(“发送图片大小\n”);
写入(套接字(void*)和大小,sizeof(int));
//以字节数组形式发送图片
printf(“将图片作为字节数组发送\n”);
当我们得到由信号引起的错误时,请执行{//读取。
stat=read(套接字和读取缓冲区,255);
printf(“读取的字节数:%i\n”,stat);
}而(stat<0);
printf(“套接字中的接收数据\n”);
printf(“套接字数据:%c\n”,读取缓冲区);
而(!feof(图片)){
//while(数据包索引=1){
//从文件读入我们的发送缓冲区
read_size=fread(发送缓冲区,1,sizeof(发送缓冲区)-1,图片);
//通过我们的套接字发送数据
做{
stat=写入(套接字、发送缓冲区、读取大小);
}而(stat<0);
printf(“数据包编号:%i\n”,数据包索引);
printf(“发送的数据包大小:%i\n”,读取大小);
printf(“\n”);
printf(“\n”);
数据包索引++;
//调零发送缓冲区
bzero(发送缓冲区,sizeof(发送缓冲区));
}
}
int main(int argc,char*argv[])
{
intsocket\u desc,new\u socket,c,read\u size,buffer=0;
服务器、客户端中的结构sockaddr_;
char*readin;
//创建套接字
socket\u desc=socket(AF\u INET,SOCK\u STREAM,0);
如果(套接字描述==-1)
{
printf(“无法创建套接字”);
}
//在结构中准备sockaddr_
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=INADDR\u ANY;
server.sin_port=htons(8000);
//束缚
if(绑定(socket_desc,(struct sockaddr*)&server,sizeof(server))<0
{
看跌期权(“绑定失败”);
返回1;
}
看跌期权(“绑定完成”);
//听
听(插座描述,3);
//接受和传入连接
puts(“等待传入连接…”);
c=sizeof(结构sockaddr_in);
if((new_socket=accept(socket_desc,(struct sockaddr*)和client,(socklen_t*)和c))){
看跌期权(“已接受连接”);
}
fflush(stdout);

if(new_socket这可能是因为您使用了所有可用的fd,因为您从未关闭任何文件描述符并一直打开它们。您确定从未将
“错误打开图像文件”
行视为输出吗?如果这样做,那么您只需尝试
fseek(NULL)
,但效果不太好

你的代码里有很多奇怪的东西

为什么在
memset()上使用
bzero()

为什么使用
printf(%c)
而不是
printf(%s)

编辑:也
使用名称空间std
;我认为在c语言中没有多大意义

你为什么用这个

do{
    stat = write(socket, send_buffer, read_size);  
}while (stat < 0);
do{
stat=写入(套接字、发送缓冲区、读取大小);
}而(stat<0);
意思是只要有错误就写。读也是如此。而且,写可能并不总是一次写入整个数据。这意味着你需要检查它是否写入了

为什么保留未使用的变量,如
验证
。
您可能应该使用编译标志来防止这些。如果您使用的是clang或gcc,则可以将
-Wall-Wextra
添加到编译行中


您可以尝试使用valgrind来查找错误:
valgrind./your_program您的参数
它将为您提供有关程序失败位置的信息。如果您使用它,请确保在编译行中添加调试符号

。首先,请记住JPEG文件是二进制文件,它不能被处理创建一个文本文件。若要继续,您不需要将整个字符串
“Got it”
作为回复发送,
sizeof(int)!=strlen(buffer)
。最后,无论何时发送或接收字符串,请记住终止它们。最后一点,您调用的许多函数的错误可能比您报告的要多,并且如果在套接字上出现
读取
错误,在大多数情况下,重试接收操作是没有用的(相反,您可能会出现无限
读取
循环)。请注意,
ftell()
返回
long
,而不是
int
。和
read()
/
write()
返回
ssize\t
,而不是
int
。函数以这种方式定义是有原因的。另外,请阅读
sendfile()
的手册页:
do{
    stat = write(socket, send_buffer, read_size);  
}while (stat < 0);