- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我做了一个应该传输文件的服务器和客户端。我试图让它读取整个文件并发送。但现在我看到了,我遇到了问题。服务器应在客户端连接时自动发送文件。但是文件是空的,不知道问题出在哪里您可以看到我正在尝试发送 .txt 文件。但我希望以后发送一个大文件,但不超过 1MB。)
编辑:
图片在这里:http://img819.imageshack.us/img819/8259/aadi.jpg
问题:我收到的文件已经损坏,无法使用。
服务器:
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#define Port 6000
SOCKET Socket, Sub;
WSADATA Winsock;
sockaddr_in Addr;
sockaddr_in IncomingAddress;
int AddressLen = sizeof(IncomingAddress);
int main()
{
WSAStartup(MAKEWORD(2, 2), &Winsock); // Start Winsock
if(LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) // Check version
{
WSACleanup();
return 0;
}
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&Addr, sizeof(Addr));
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
bind(Socket, (sockaddr*)&Addr, sizeof(Addr));
if(listen(Socket, 1) == SOCKET_ERROR)
{
printf("listening error\n");
}
else
{
printf("listening ok\n");
}
if(Sub = accept(Socket, (sockaddr*)&IncomingAddress, &AddressLen))
{
char *ClientIP = inet_ntoa(IncomingAddress.sin_addr);
int ClientPort = ntohs(IncomingAddress.sin_port);
printf("Client conncted!\n");
printf("IP: %s:%d\n", ClientIP, ClientPort);
printf("Sending file .. \n");
FILE *File;
char *Buffer;
unsigned long Size;
File = fopen("C:\\Prog.rar", "rb");
if(!File)
{
printf("Error while readaing the file\n");
getchar();
return 0;
}
fseek(File, 0, SEEK_END);
Size = ftell(File);
fseek(File, 0, SEEK_SET);
Buffer = new char[Size];
fread(Buffer, Size, 1, File);
char cSize[MAX_PATH];
sprintf(cSize, "%i", Size);
fclose(File);
send(Sub, cSize, MAX_PATH, 0); // File size
//int len = Size;
//char *data = Buffer;
int Offset = 0;
while(Size > Offset)
{
int Amount = send(Sub, Buffer + Offset, Size - Offset, 0);
if(Amount <= 0)
{
cout << "Error: " << WSAGetLastError() << endl;
break;
}
else
{
Offset += Amount;
printf("2\n");
}
}
free(Buffer);
closesocket(Sub);
closesocket(Socket);
WSACleanup();
}
getchar();
return 0;
}
客户:
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
SOCKET Socket;
WSADATA Winsock;
sockaddr_in Addr;
int Addrlen = sizeof(Addr);
int main()
{
WSAStartup(MAKEWORD(2, 2), &Winsock); // Start Winsock
if(LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) // Check version
{
WSACleanup();
return 0;
}
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&Addr, sizeof(Addr)); // clear the struct
Addr.sin_family = AF_INET; // set the address family
Addr.sin_addr.s_addr = inet_addr("127.0.0.1");
Addr.sin_port = htons(6000); // set the port
if(connect(Socket, (sockaddr*)&Addr, sizeof(Addr)) < 0)
{
printf("Connection failed !\n");
getchar();
return 0;
}
printf("Connection successful !\n");
printf("Receiving file .. \n");
int Size;
char *Filesize = new char[1024];
if(recv(Socket, Filesize, 1024, 0)) // File size
{
Size = atoi((const char*)Filesize);
printf("File size: %d\n", Size);
}
char *Buffer = new char[Size];
//int len = Size;
//char *data = Buffer;
int Offset = 0;
while(Size > Offset)
{
int Amount = recv(Socket, Buffer + Offset, Size - Offset, 0);
if(Amount <= 0)
{
cout << "Error: " << WSAGetLastError() << endl;
break;
}
else
{
Offset += Amount;
printf("2\n");
}
}
FILE *File;
File = fopen("Prog.rar", "wb");
fwrite(Buffer, 1, Size, File);
fclose(File);
getchar();
closesocket(Socket);
WSACleanup();
return 0;
}
最佳答案
send
API 可能无法发送您请求发送的所有数据。所以,你要注意返回值,从上次发送结束的地方重试发送。例如:
offset = 0;
while (offset < bufsize) {
r = send(socket, buf+offset, bufsize-offset);
if (r <= 0) break;
offset += r;
}
虽然您正在为文件传输做类似的事情,但您不确定文件大小是否属于这种情况。
发送文件大小时,只需要发送代表大小的字符串即可,不需要发送整个MAX_PATH
。然后接收方需要解析第一个字符串以确定大小,但是在第一个字符串结束后读入的任何数据都需要被视为文件的一部分。但是,由于您正在尝试发送 MAX_PATH
,接收方应该收到相同的数量。您的客户端代码收到 1024 字节,但没有迹象表明这与 MAX_PATH
大小相同。
recv
API 返回的字节数也可能少于请求的字节数。您使用循环来处理读取文件,但您可能需要一个循环来读取包含文件大小的整个消息。
在您的客户端接收循环中,您正在递增 data
指针。这使得以后无法写出该文件。不过,您已经有了 Buffer
,因此请使用它来写出您的文件。
fwrite(Buffer, 1, len, File);
如果您在执行套接字 I/O 时遇到错误,您可以使用 WSAGetLastError()
检索错误,或者您可以在套接字上发出 getsockopt()
SO_ERROR
选项。这些可能返回不同的值,但错误原因应该是相关的。
关于c++ - 读取整个文件并通过套接字发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15176213/
我使用下拉菜单提供一些不同的链接,但我希望这些链接在同一选项卡中打开,而不是在新选项卡中打开。这是我找到的代码,但我对 Javascript 非常缺乏知识 var urlmenu = docume
我对 javascript 不太了解。但我需要一个垂直菜单上的下拉菜单,它是纯 JavaScript,所以我从 W3 复制/粘贴脚本:https://www.w3schools.com/howto/t
我已经坐了 4 个小时,试图让我的导航显示下 zipper 接垂直,但它继续水平显示它们。我无法弄清楚为什么会发生这种情况或如何解决它。 如果有人能告诉我我做错了什么,我将不胜感激。我有一个潜移默化的
我正在尝试创建选项卡式 Accordion 样式下拉菜单。我使用 jQuery 有一段时间了,但无法使事件状态达到 100%。 我很确定这是我搞砸的 JS。 $('.service-button').
对于那些从未访问过 Dropbox 的人,这里是链接 https://www.dropbox.com/ 查看“登录”的下拉菜单链接。我如何创建这样的下 zipper 接? 最佳答案 这是 fiddle
我正在制作一个 Liferay 主题,但我在尝试设计导航菜单的样式时遇到了很多麻烦。我已经为那些没有像这样下拉的人改变了导航链接上的经典主题悬停功能: .aui #navigation .nav li
如果您将鼠标悬停在 li 上,则会出现一个下拉菜单。如果您将指针向下移至悬停时出现的 ul,我希望链接仍然带有下划线,直到您将箭头从 ul 或链接移开。这样你就知道当菜单下拉时你悬停在哪个菜单上。 知
我有一个带有多个下拉菜单的导航栏。因此,当我单击第一个链接时,它会打开下拉菜单,但是当我单击第二个链接时,第一个下拉菜单不会关闭。 (所以如果用户点击第二个链接我想关闭下拉菜单) // main.js
我正在尝试制作一个导航下拉菜单(使用 Bootstrap 3),其中链接文本在同一行上有多个不同的对齐方式。 在下面的代码中,下拉列表 A 中的链接在 HTML 中有空格字符来对齐它们,但是空白被忽略
我希望有人能帮我解决这个 Bootstrap 问题,因为我很困惑。 有人要求我在底部垂直对齐图像和其中包含图像的链接。 我面临的问题是他们还希望链接在链接/图像组合上具有 pull-right,这会杀
我正在构建一个 Rails 应用程序,并希望指向我的类的每个实例的“显示”页面的链接显示在“索引”页面的下拉列表中。我目前正在使用带有 options_from_collection_for_sele
我有以下 Bootstrap3 导航菜单 ( fiddle here )。我想设置“突出显示”项及其子链接与下拉列表 1 和 2 链接不同的链接文本(和悬停)的样式。我还希望能够以不同于 Highli
我对导航栏中的下拉菜单有疑问。对于普通的导航链接(无下拉菜单),我将菜单文本放在 H3 中,但是当我尝试对下 zipper 接执行相同操作时,箭头不在标题旁边,而是在标题下方。我决定用 span 替换
我是一名优秀的程序员,十分优秀!