写的一个程序,WINDOWS用作服务器,LINUX下面的是客户端,LINUX向WINDOWS传输文件,大小超过2M以上,经常数据不正常,WINDOWS用的SOCKET是异步模式的,经常是LINUX下面文件早早发完了,WINDOWS那边接个2M的文件最少要3-5分钟,还卡得要死,一次输送的是1K=1024

解决方案 »

  1.   

    是否是模式问题,select 发送信号到界面时,有数据流了就直接写进文件了,猜想应该是要一个先写到缓存里面,等文件接收完了,再一次性写进文件吧
      

  2.   

    一次1K你这缓冲也有点太小了………………
    设个256KB我都觉得不过分,特别是局域网传输的时候,不要太小看网卡。另外传输文件瓶颈在于往磁盘里面写,你如果接收1KB数据就往磁盘里写1KB的话,自然会慢的多
      

  3.   

    不熟悉WINDOWS的编程,以前一直LINUX下面写程序 感觉这个服务器结构有点问题,select 通知发信号->处理信号->读数据->写缓存.因为一次发送只有1024,一个2M的文件最少发20次以上,这样回来 循环,很浪费效率.因为程序里面没有用到线程.
      

  4.   

    LRESULT CTCP_IPChatDlg::OnSocket(WPARAM wParam,LPARAM lParam)
    { char test_str[201] = {0};
    CString show_msg;//
    CString recv_file_name;
    char rcv_msg[1400] = {0} ;
    CString list_text;
    int list_num = 0;//list_Box列表的条目个数
    int i = 0
    char function_num[3];
    static CFile *cur_file;
    static CString rcv_file_cache;//接收文件缓存区 switch (lParam)
    {
    case FD_ACCEPT:
    {
    show_msg = "";
    int lenth=sizeof(client_addr);     
    cur_client.client_socket = ::accept(server_socket,(struct sockaddr*)&client_addr,&lenth); cur_client.client_socket = cur_client.client_socket;
    for(i=0;i<30;i++)
    {
    if(connect_client[i].clientIP_addr == "")
    {
    connect_client[i].client_socket = cur_client.client_socket;
    connect_client[i].clientIP_addr = ::inet_ntoa(client_addr.sin_addr);
    cur_client.clientIP_addr = ::inet_ntoa(client_addr.sin_addr);
    break;
    }
    //memset(&connect_client[i],0x00,sizeof(struct client_msg_t));
    }
    client_num = client_num + 1;
    //显示信息
    show_msg.Format(L"有%d客户已经连接上了",client_num);
    GetDlgItem(IDC_MsgEdit)->SetWindowText(show_msg);
    show_msg += cur_client.clientIP_addr;
    show_msg+="\r\n";
    show_msg+="登陆\r\n";
    GetDlgItem(IDC_MsgEdit)->SetWindowText(show_msg);
    //GetDlgItem(IDC_MsgEdit)->SetWindowText(L"\r\n客户端1说:你好!");
    break;
    }
    case FD_READ:

    show_msg = ""; ::recv(wParam,rcv_msg,1024,0); if ( rcv_msg[0] != 0)
    {
    for(i=0;i<30;i++)//遍历,看是与那个客户端进行传输文件
    {
    if((connect_client[i].client_socket == wParam)&&(connect_client[i].recv_file_lenth>0))//recv_file_lenth大于0,表示进行文件传输
    {
    rcv_file_cache += rcv_msg;
    connect_client[i].recv_file_lenth = connect_client[i].recv_file_lenth - strlen(rcv_msg);
    if (connect_client[i].recv_file_lenth <= 0)

    //文件接收完写入文件
    if(cur_file!= NULL)
    cur_file->Write(&rcv_file_cache,rcv_file_cache.GetLength());
    cur_file->Close();
    //显示信息
    GetDlgItem(IDC_MsgEdit)->GetWindowText(show_msg);
    show_msg +="文件接收完成\r\n";
    GetDlgItem(IDC_MsgEdit)->SetWindowText(show_msg);
    }
    }
    else
    {
    memset(function_num,0x00,3);
    strncpy(function_num,rcv_msg+1,2);
    if (strcmp(function_num,"50") == 0)//功能号50,要接收文件
    {
    char temp[20];
    int file_name_lenth = 0;
    int file_lenth = 0;
    char file_name[30];
    rcv_file_cache = "";//接收文件缓存
    memset(temp,0x00,20);
    memset(file_name,0x00,30);
    strncpy(temp,rcv_msg+3,2);
    file_name_lenth = atoi(temp);//文件名的长度
    strncpy(file_name,rcv_msg+5,file_name_lenth);//文件名
    memset(temp,0x00,20);
    strncpy(temp,rcv_msg+5+file_name_lenth,strlen(rcv_msg)-5-file_name_lenth );
    connect_client[i].recv_file_lenth = atoi(temp);//文件的长度 CString   csFilter; //文件类型
    CString file_name_str;
    file_name_str = file_name;
    {
    GetDlgItem(IDC_MsgEdit)->GetWindowText(show_msg);
    show_msg += "\r\n";
    show_msg += file_name; GetDlgItem(IDC_MsgEdit)->SetWindowText(show_msg);
    }
    CFileDialog filedlg(false,NULL,file_name_str,OFN_HIDEREADONLY   |   OFN_OVERWRITEPROMPT,NULL,NULL);//定义文件对话框 filedlg.m_ofn.lpstrFileTitle = (LPWSTR) file_name;//在对话框中显示文件名
    if(filedlg.DoModal() == IDOK)//显示文件保存对话框
    {
    CString str;
    str = filedlg.GetPathName();//保存的文件路径,包括了文件名
    cur_file = new CFile(str,CFile::modeCreate | CFile::modeWrite);//根据文件名创建文件
    if (cur_file == NULL)//如果文件不存在
    {
    //return;
    }
    }
    ::send(connect_client[i].client_socket,"OK",3,0);//应答OK

    }
    else//普通聊天通讯
    {
    //显示聊天的内容
    GetDlgItem(IDC_MsgEdit)->GetWindowText(show_msg);
    show_msg += "\r\n";
    show_msg +=connect_client[i].clientIP_addr;
    show_msg += "对您说:";
    show_msg += rcv_msg;
    show_msg += "";
    GetDlgItem(IDC_MsgEdit)->SetWindowText(show_msg);
    if (strcmp(rcv_msg,"recv_file") == 0)//如果是recv_file,应答OK
    {
    ::send(connect_client[i].client_socket,"OK",3,0);

    }
    } }
    break;
    } }
    break;
    }
    case FD_CLOSE:
    {
    show_msg = "";
    list_text = "";
    list_num = ((CListBox *)GetDlgItem(IDC_ClientList))->GetCount( ); ::closesocket(wParam);//关闭套接字
    for(i=0;i<30;i++)
    {
    if(connect_client[i].client_socket == wParam)
    {
    //显示下线通知
    GetDlgItem(IDC_MsgEdit)->GetWindowText(show_msg);
    show_msg += "\r\n";
    show_msg += connect_client[i].clientIP_addr;
    show_msg += "客户端已经下线!\r\n";
    GetDlgItem(IDC_MsgEdit)->SetWindowText(show_msg);

    //删除下线客户的在列表框的信息
    for(i=0;i<list_num;i++)
    {
    ((CListBox *)GetDlgItem(IDC_ClientList))->GetText(i,list_text);
    if ( list_text == connect_client[i].clientIP_addr )//函数可以根据当前列表框的序号读取当前选择的项目
    {
    ((CListBox *)GetDlgItem(IDC_ClientList))->DeleteString(i);//(::inet_ntoa(client_addr.sin_addr));
    break;
    }
    }
    connect_client[i].client_socket = 0;
    connect_client[i].clientIP_addr = "";
    connect_client[i].client_name = "";
    break;
    }
    }
    break;
    }
    }
    return TRUE;
    }