conutd 2022-10-30 16:53 采纳率: 50%
浏览 115
已结题

TCP客户端发送图片,服务器端进行接收,接受后的图片显示不出来

TCP客户端发送图片,服务器端进行接受
运行结果及报错内容
客户端
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <thread>
#include <fstream>
#include <stdlib.h>
#include <fcntl.h>
#include "cs.h"

using namespace std;

#define PORT 8889
#define MSG_SIZE 4096
#define MAX_LINE 5
#define IP "127.0.0.1"



int client()
{
    char client_MSG[MSG_SIZE], server_MSG[MSG_SIZE];

    //初始化TCP结构体
    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_port = (PORT);
    serverAddr.sin_family = AF_INET;

    if (inet_pton(AF_INET, IP, (void *)&serverAddr.sin_addr) <= 0)
    {
        perror("client inet_pton err!");
        return -1;
    }

    //创建socket套接字
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0)
    {
        perror("server socket err!");
        return -1;
    }

    // connect连接
    if (connect(socket_fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
    {
        perror("client connect err!");
        return -1;
    }

    cout << "Connect Success!." << endl;
    cin.ignore(1024, '\n'); // 去除上一个cin残留在缓冲区的\n

    // thread th;
    // th = thread(recv_server,socket_fd , client_MSG);

    //打开照片的文件描述符
    // char yuv_data[3110];
    FILE *fp = fopen("/home/hq/1.jpg", "r");
    // int fd1=open("/home/nvidia/1.jpg", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fp == NULL)
    {
        perror("fopen err!");
        return -1;
    }

    char buff[1024] = {0};
    char buf[1034] = {1, 2};

    //计算文件大小
    fseek(fp, 0L, SEEK_END);
    int file_len = ftell(fp);

    cout << "文件大小= " << file_len << endl;
    fseek(fp, 0L, SEEK_SET);

    while (1)
    {

        int len = fread(buff, 1, sizeof(buff), fp); // 1024

        if (0 == len)
        {
            cout << "read end...........\n";
            fseek(fp, 0, SEEK_SET);
            break;
        }

        buf[2] = len & 0xFF;
        buf[3] = (len >> 8) & 0xFF;
        buf[4] = (len >> 16) & 0xFF;
        buf[5] = (len >> 24) & 0xFF;

        //文件总大小
        buf[6] = file_len & 0xFF;
        buf[7] = (file_len >> 8) & 0xFF;
        buf[8] = (file_len >> 16) & 0xFF;
        buf[9] = (file_len >> 24) & 0xFF;

        cout << "文件大小= " << file_len << endl;

        // 1024
        memcpy(&buf[10], buff, len);

        cout << "len=" << len << endl;

        sleep(0.5);
        if (len > 0)
        {
            if (send(socket_fd, buf, len + 10, 0) < 0)
            {
                perror("client send err!");
            }
        }
        else
        continue;

#if 0
        memset(client_MSG, 0, sizeof(client_MSG));
        memset(server_MSG, 0, sizeof(server_MSG));

        
        cin.getline(client_MSG, sizeof(client_MSG)); // 不用cin,因为不能含空格

        if (strncmp(client_MSG, "quit", 4) == 0)
        {
            break;
        }

        //向服务器端发消息
        if (send(socket_fd, client_MSG, strlen(client_MSG), 0) < 0)
        {
            perror("client send err!");
            return -1;
        }

        cout << "send msg to <" << serverAddr.sin_addr.s_addr << ">--> " << client_MSG << endl;

        // 接收服务器的消息
        int s_len=recv(socket_fd,server_MSG,sizeof(server_MSG),0);
        if(s_len <=0 )
        {
            perror("client recv err!");
            return -1;
        }

        server_MSG[s_len]='\0';

        cout<<"recv msg form <"<<serverAddr.sin_addr.s_addr<<">--> "<<server_MSG<<endl;
#endif
    }
    fclose(fp);
}


```c++
服务器端
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <thread>
#include <stdlib.h>
#include <fcntl.h>
#include "cs.h"

using namespace std;

#define PORT 8889
#define MSG_SIZE 4096
#define MAX_LINE 5

int server()
{
    char client_MSG[MSG_SIZE], server_MSG[MSG_SIZE];

    //初始化TCP结构体
    struct sockaddr_in serverAddr;
    serverAddr.sin_port = (PORT);
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    //创建socket套接字
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0)
    {
        perror("server socket err!");
        return -1;
    }

    // bind绑定套接字
    if (bind(socket_fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
    {
        perror("server bind err!");
        return -1;
    }

    // listen被动监听
    if (listen(socket_fd, MAX_LINE) < 0)
    {
        perror("server listen err!");
        return -1;
    }

    cout << "Listening........\n";
    int client_fd;

    FILE *fp = fopen("/home/hq/8.jpg", "w");
    if (fp == NULL)
    {
        perror("fopen err!");
        return -1;
    }

    static int num = 0;

    while (1)
    {
        memset(client_MSG, 0, sizeof(client_MSG));
        memset(server_MSG, 0, sizeof(server_MSG));

        struct sockaddr_in clientAddr;
        socklen_t lens = sizeof(clientAddr);

        //返回用于通信的文件描述符
        client_fd = accept(socket_fd, (struct sockaddr *)&clientAddr, &lens);
        if (client_fd < 0)
        {
            perror("server accept err!");
            return -1;
        }

        cout << "server: connection from " << clientAddr.sin_addr.s_addr
             << ", port " << PORT
             << ", socket " << client_fd << endl;

        while (1)
        {

            char buf[2048] = {0};

            int rd = 0;
            

            int w_len = 0, file_len = 0,len=0;

            int i = 0;

            static int count = 0;

            while (1)
            {
                rd = recv(client_fd, &buf[i], sizeof(buf), 0);
                
                cout<<"recv = "<<rd<<endl;

                if (rd <= 0)
                {
                    cout << "RD<=0跳出" << endl;
                    break;
                }

                if (buf[i] == 1)
                {
                    ++i;
                    cout << "buf1==0x90-" << i << endl;
                }
                    

                if (buf[i] == 2)
                {
                    ++i;
                    cout << "buf1==0x81-" << i << endl;
                }

                len = (buf[i] | buf[i + 1] << 8 | buf[i + 2] << 16 | buf[i + 3] << 24);

                if (len > 0)
                {
                    
                    i += 4;
                    cout << "send的长度:" << len <<" "<<"i="<< i<<endl;
                }

                   file_len = (buf[i] | buf[i + 1] << 8 | buf[i + 2] << 16 | buf[i + 3] << 24);

                    i += 4;
                    cout << "file的长度:" << file_len <<" "<< "i="<< i<<endl;

                if (file_len < 0)
                {
                    cout << "file_len_获取失败\n";
                    // return -1;
                }
                
                  cout<<"進入寫入------------\n";
                  w_len = fwrite(&buf[i], 1, len, fp);
                  memcpy(buf,&buf[i+len],(sizeof(buf)-strlen(&buf[i+len])));
                  i=0;

                num = w_len + num;

                if (num >= file_len)
                {
                    if (num == file_len)
                    {
                        cout << "文件大小已经读取完成\n";
                        fseek(fp, 0, SEEK_SET);
                        count++;
                        num = 0;
                        return -1;
                    }
                }
                
                if(i==(sizeof(buf)))
                {
                    cout<<"buf==2048"<<endl;
                    // i=0;
                    break;
                }

            }

            //关闭通信套接字
            close(client_fd);

            cout << "当前客户端已结束通信,是否继续等待其他客户端?(1 - 是, 0 - 否)" << endl;
            bool isContinue = false;
            cin >> isContinue;
            if (!isContinue)
            {
                break;
            }
        }
    }
    fclose(fp);
    close(socket_fd);
    return 0;
}


``` 服务器端收2048个,报头含有标志和数据长度,图片传输过去服务器写入数据不对,提醒段错误

  • 写回答

8条回答 默认 最新

  • 叶落花枯 2022-10-30 17:37
    关注

    309行的 memcpy(buf,&buf[i+len],(sizeof(buf)-strlen(&buf[i+len]))); 是干什么的,把自身缓冲区后面的数据拷贝到自己缓冲区,有什么意义?

    评论

报告相同问题?

问题事件

  • 系统已结题 11月7日
  • 创建了问题 10月30日

悬赏问题

  • ¥15 笔记本电脑持续蓝屏重启,昨晚放电后乱点进入indyde
  • ¥15 fcloudflare域名已经用了一年了,突然之间finalshell证书签发错误怎么解决
  • ¥15 近端策略优化 PPO | 损失值计算问题
  • ¥20 高通移动端,安卓12,如何让wifi无视国家码启动6Gwifi,重新开机无需干涉自动连接
  • ¥15 Hadoop实训论文成品! 任意标题 价格可私 急
  • ¥15 程序实在不会写,要秃了
  • ¥15 pycharm导入不了自己的包
  • ¥15 本人本科机械,目前研一。没有深度学习基础,目前对研究生课题一片迷茫,请教各位!
  • ¥15 关于R语言单因素与多因素线性回归的平均值
  • ¥15 服务器清除BIOS之后引导不了