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