use*_*182 9 c++ sockets networking image file
我正在编写一个小型的C程序,以便能够使用TCP/IP套接字在两台计算机之间(从运行Linux的服务器到客户端)传输图像文件,但由于我的图片出现在另一侧,似乎出现了错误损坏.
我的服务器的代码是这样的:
#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;
char send_buffer[10240], verify;
picture = fopen("2.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);
//Send Picture Size
printf("Sending Picture Size\n");
write(socket, (void *)&size, sizeof(int));
if(read_size = read(socket, &verify , sizeof(char)) < 0) {
puts("\nError Receiving Verification");
}
if(verify == '1'){
printf("5\n");
//Send Picture as Byte Array
printf("Sending Picture as Byte Array\n");
while(!feof(picture)) {
//Read from the file into our send buffer
read_size = fread(send_buffer, 1, sizeof(send_buffer)-1, picture);
//Send data through our socket
write(socket, send_buffer, read_size);
//Wait for the verify signal to be received
while(read(socket, &verify , sizeof(char)) < 0);
if(verify != '1') {
printf("Error Receiving the Handshake signal\n %s",&verify);
}
verify = '';
//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( 8889 );
//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;
}
send_image(new_socket);
close(socket_desc);
fflush(stdout);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
接收数据的客户端代码如下:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<sys/ioctl.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<iostream>
#include<errno.h>
using namespace std;
//This function is to be used once we have confirmed that an image is to be sent
//It should read and output an image file
int receive_image(int socket){
int buffersize = 0, recv_size = 0,size = 0, read_size, write_size;
char imagearray[10241],verify = '1';
FILE *image;
//Find the size of the image
read(socket, &size, sizeof(int));
//Send our verification signal
write(socket, &verify, sizeof(char));
//Make sure that the size is bigger than 0
if(size <= 0 ){
printf("Error has occurred. Size less than or equal to 0\n");
return -1;
}
image = fopen("2.jpg", "w");
if( image == NULL) {
printf("Error has occurred. Image file could not be opened\n");
return -1;
}
//Loop while we have not received the entire file yet
while(recv_size < size) {
ioctl(socket, FIONREAD, &buffersize);
//We check to see if there is data to be read from the socket
if(buffersize > 0 ) {
if(read_size = read(socket,imagearray, buffersize) < 0){
printf("%s", strerror(errno));
}
//Write the currently read data into our image file
write_size = fwrite(imagearray,1,(buffersize), image);
if(write_size != buffersize) {
printf("write and buffersizes wrong");
}
if(read_size !=write_size) {
printf("error in read write");
}
//Increment the total number of bytes read
recv_size += read_size;
//Send our handshake verification info
write(socket, &verify, sizeof(char));
}
}
fclose(image);
printf("Image successfully Received!\n");
return 1;
}
int main(int argc , char *argv[])
{
int socket_desc;
struct sockaddr_in server;
char *parray;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1) {
printf("Could not create socket");
}
memset(&server,0,sizeof(server));
server.sin_addr.s_addr = inet_addr("10.42.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8889 );
//Connect to remote server
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) {
cout<<strerror(errno);
close(socket_desc);
puts("Connect Error");
return 1;
}
puts("Connected\n");
receive_image(socket_desc);
close(socket_desc);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我一把吗?在我的生活中,我无法弄清楚这个错误.
编辑:我已经改变了fwrites和freads回到常规的写入和读取,它仍然发送一个损坏的图像
你有很多问题:
"rb"用于读取,"wb"写入),而不是默认文本模式.在Windows(以及任何其他进行行结束转换的系统)上,stdio库在写入时将LF(字节0x0A)转换为CRLF对(两个字节0x0D 0x0A),并在读取时执行反向转换.对于像JPEG文件这样的非文本数据,这会破坏数据.send()/ write()返回一个正值,那么另一个对等体就会接收到那么多字节.send()/ write()可能不会发送您要求的所有数据 - 他们可能会进行部分发送.如果发生这种情况,您需要继续尝试在循环中发送剩余的缓冲区.sizeof(char)保证在C语言标准下为1,很少需要说明什么sizeof(char)时候没有它你的代码会更清晰ioctl来确定可以在不阻塞的情况下读取多少数据,因为您只是再次循环 - 在没有可用数据的情况下,您的代码将以100%CPU旋转.只是让read()呼叫阻止.如果您在笔记本电脑上运行此代码,您的电池将会感谢您.ntohl(3)和htonl(3)函数对4字节值执行这些转换.小智 5
现在很好用.
最好,
马里奥.
客户:
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<unistd.h>
#include<iostream>
#include<fstream>
#include<errno.h>
using namespace std;
//This function is to be used once we have confirmed that an image is to be sent
//It should read and output an image file
int receive_image(int socket)
{ // Start function
int buffersize = 0, recv_size = 0,size = 0, read_size, write_size, packet_index =1,stat;
char imagearray[10241],verify = '1';
FILE *image;
//Find the size of the image
do{
stat = read(socket, &size, sizeof(int));
}while(stat<0);
printf("Packet received.\n");
printf("Packet size: %i\n",stat);
printf("Image size: %i\n",size);
printf(" \n");
char buffer[] = "Got it";
//Send our verification signal
do{
stat = write(socket, &buffer, sizeof(int));
}while(stat<0);
printf("Reply sent\n");
printf(" \n");
image = fopen("capture2.jpeg", "w");
if( image == NULL) {
printf("Error has occurred. Image file could not be opened\n");
return -1; }
//Loop while we have not received the entire file yet
int need_exit = 0;
struct timeval timeout = {10,0};
fd_set fds;
int buffer_fd, buffer_out;
while(recv_size < size) {
//while(packet_index < 2){
FD_ZERO(&fds);
FD_SET(socket,&fds);
buffer_fd = select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
if (buffer_fd < 0)
printf("error: bad file descriptor set.\n");
if (buffer_fd == 0)
printf("error: buffer read timeout expired.\n");
if (buffer_fd > 0)
{
do{
read_size = read(socket,imagearray, 10241);
}while(read_size <0);
printf("Packet number received: %i\n",packet_index);
printf("Packet size: %i\n",read_size);
//Write the currently read data into our image file
write_size = fwrite(imagearray,1,read_size, image);
printf("Written image size: %i\n",write_size);
if(read_size !=write_size) {
printf("error in read write\n"); }
//Increment the total number of bytes read
recv_size += read_size;
packet_index++;
printf("Total received image size: %i\n",recv_size);
printf(" \n");
printf(" \n");
}
}
fclose(image);
printf("Image successfully Received!\n");
return 1;
}
int main(int argc , char *argv[])
{
int socket_desc;
struct sockaddr_in server;
char *parray;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1) {
printf("Could not create socket");
}
memset(&server,0,sizeof(server));
server.sin_addr.s_addr = inet_addr("10.0.0.30");
server.sin_family = AF_INET;
server.sin_port = htons( 8889 );
//Connect to remote server
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) {
cout<<strerror(errno);
close(socket_desc);
puts("Connect Error");
return 1;
}
puts("Connected\n");
receive_image(socket_desc);
close(socket_desc);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
服务器:
#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("capture.jpeg", "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( 8889 );
//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;
}
send_image(new_socket);
close(socket_desc);
fflush(stdout);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30362 次 |
| 最近记录: |