我是编程winsock的新手,我有这个代码:服务器运行,然后我们运行客户端"客户端localhost"从cmd,文件从客户端发送到服务器有时服务器收到txt文件,有时没有正确的数据,我发现像垃圾或错误的数据,所以请帮助我,我会发布代码:
服务器:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
using namespace std;
#define DEFAULT_PORT "1234"
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
// printf("iResult : %d\n", iResult);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
//printf("again :iResult : %d\n", iResult);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// printf("if error no showed we continue ", iResult);
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("accepting ", iResult);
// No longer need server socket
closesocket(ListenSocket);
// Receive until the peer shuts down the connection
///////recive a file ////////
int Size;
char *Filesize = new char[1024];
if(recv(ClientSocket, Filesize, 1024, 0)) // File size
{
Size = atoi((const char*)Filesize);
printf("File size: %d\n", Size);
}
char *Buffer = new char[Size];
int bytes_read;
/////////////test code start
while (1) {
// Read data into buffer. We may not have enough to fill up buffer, so we
// store how many bytes were actually read in bytes_read.
bytes_read = recv(ClientSocket, Buffer, Size, 0);
if (bytes_read == 0) // We're done reading from the file
{
Buffer[Size]='\0';
FILE *File;
File = fopen("F:\\file2.txt", "wb");
fwrite((const char*)Buffer, 1, Size, File);
//string str=string(Buffer);
//printf(str);
//std::cout<<str;
fclose(File);
break;
}
if (bytes_read < 0) {
// handle errors
cout << "file read error";
}
}
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
system("PAUSE");
return 0;
}
客户:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
using namespace std;
#define DEFAULT_PORT "1234"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
int iResult;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
//Send A File ///
FILE *File;
char *Buffer;
unsigned long Size;
File = fopen("E:\\file1.txt", "rb");
//File = fopen("file1.txt", "rb");
if(!File)
{
printf("Error while readaing the file\n");
}
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);
//printf("file size is %s ",cSize);
fclose(File);
//Buffer[Size]='\0';
send(ConnectSocket, cSize, MAX_PATH, 0); // File size
send(ConnectSocket, Buffer, Size, 0); // File Binary
ZeroMemory(&Buffer, sizeof(Buffer));
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
答案 0 :(得分:0)
正如@HarryJohnston在评论中所说,send()
和recv()
不匹配。您使用260字节缓冲区将文件大小作为可变长度字符串发送,然后使用1000字节缓冲区接收它(将接收文件大小和文件数据的一部分)并转换为整个缓冲区为整数,无论使用多少字符来格式化字符串值。因此,您需要做的第一件事就是首先停止将文件大小作为可变长度字符串发送,而是将其作为固定长度的二进制整数发送。然后接收器确切地知道要读取多少字节来接收文件大小,然后可以读完整数所说的读取的字节数。
您也忽略了返回值,没有检查错误,没有考虑send()
和recv()
传输的字节数少于请求的数量,并且通常无法正确管理文件数据。
尝试更像这样的事情:
服务器:
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#define DEFAULT_PORT "1234"
bool readData(SOCKET sock, void *buff, int buflen)
{
char *pbuf = (char*) buff;
int bytes_read;
while (buflen > 0)
{
bytes_read = recv(sock, pbuf, buflen, 0);
if (bytes_read <= 0)
{
if (bytes_read == SOCKET_ERROR)
printf("recv failed with error: %d\n", WSAGetLastError());
else
printf("client disconnected\n");
return false;
}
pbuf += bytes_read;
buflen -= bytes_read;
}
return true;
}
int __cdecl main(void)
{
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
// printf("iResult : %d\n", iResult);
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
// Resolve the server address and port
struct addrinfo hints = {0};
struct addrinfo *result = NULL;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
//printf("again :iResult : %d\n", iResult);
if ( iResult != 0 )
{
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for listening for client
SOCKET ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
printf("socket failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
// start listening
iResult = listen(ListenSocket, 1);
if (iResult == SOCKET_ERROR)
{
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
SOCKET ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("client connected\n");
// Receive until the peer sends a file or shuts down the connection
unsigned long FileSize;
if (!readData(ClientSocket, &FileSize, sizeof(FileSize)))
{
closesocket(ClientSocket);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
FileSize = ntohl(FileSize);
printf("File size: %lu\n", FileSize);
FILE *File = fopen("F:\\file2.txt", "wb");
if (!File)
{
printf("fopen failed with error\n");
closesocket(ClientSocket);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
if (FileSize > 0)
{
char Buffer[1024];
int bytes_to_read;
do
{
if (FileSize <= sizeof(Buffer))
bytes_to_read = (int)FileSize;
else
bytes_to_read = sizeof(Buffer);
if (!readData(ClientSocket, Buffer, bytes_to_read))
{
fclose(File);
remove("F:\\file2.txt");
closesocket(ClientSocket);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
if (fwrite(Buffer, bytes_to_read, 1, File) != 1)
{
printf("fwrite failed with error\n");
fclose(File);
remove("F:\\file2.txt");
closesocket(ClientSocket);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
FileSize -= bytes_to_read;
}
while (FileSize > 0);
}
fclose(File);
printf("file received\n");
iResult = shutdown(ClientSocket, SD_BOTH);
if (iResult == SOCKET_ERROR)
{
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
closesocket(ListenSocket);
WSACleanup();
system("PAUSE");
return 0;
}
客户:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_PORT "1234"
bool sendData(SOCKET sock, void *buff, int buflen)
{
char *pbuf = (char*) buff;
int bytes_sent;
while (buflen > 0)
{
bytes_sent = send(sock, pbuf, buflen, 0);
if (bytes_sent <= 0)
{
if (bytes_sent == SOCKET_ERROR)
printf("send failed with error: %d\n", WSAGetLastError());
else
printf("client disconnected\n");
return false;
}
pbuf += bytes_sent;
buflen -= bytes_sent;
}
return true;
}
int __cdecl main(int argc, char **argv)
{
// Validate the parameters
if (argc != 2)
{
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
struct addrinfo hints = {0};
struct addrinfo *result = NULL;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
SOCKET ConnectSocket = INVALID_SOCKET;
for(struct addrinfo *ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET)
{
printf("socket failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult != SOCKET_ERROR)
break;
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET)
{
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
//Send A File ///
FILE *File = fopen("E:\\file1.txt", "rb");
if (!File)
{
printf("fopen failed with error\n");
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
if (fseek(File, 0, SEEK_END) != 0)
{
printf("fseek failed with error\n");
fclose(File);
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
unsigned long FileSize = ftell(File);
if (FileSize == EOF)
{
printf("Error getting the file size\n");
fclose(File);
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
//printf("file size is %lu\n", FileSize);
if (fseek(File, 0, SEEK_SET) != 0)
{
printf("fseek failed with error\n");
fclose(File);
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
unsigned long tmpFileSize = htonl(FileSize);
if (!sendData(ConnectSocket, &tmpFileSize, sizeof(tmpFileSize)))
{
fclose(File);
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
if (FileSize > 0)
{
char Buffer[1024];
int bytes_to_send;
do
{
if (FileSize <= sizeof(Buffer))
bytes_to_send = (int)FileSize;
else
bytes_to_send = sizeof(Buffer);
if (fread(Buffer, bytes_to_send, 1, File) != 1)
{
printf("fread failed with error\n");
fclose(File);
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
if (!sendData(ConnectSocket, Buffer, bytes_to_send))
{
fclose(File);
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
FileSize -= bytes_to_send;
}
while (FileSize > 0);
}
fclose(File);
printf("file sent\n");
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_BOTH);
if (iResult == SOCKET_ERROR)
{
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
system("PAUSE");
return 0;
}
或者,你真的应该停止将C和C ++混合在一起,使用一个或另一个,而不是两者。这是上面代码的C ++版本:
服务器:
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <algorithm>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#define DEFAULT_PORT "1234"
void winsockError(const char *func, int errcode)
{
std::ostringstream oss;
oss << func << " failed with error: " << errcode;
throw std::runtime_error(oss.str());
}
void winsockError(const char *func)
{
winsockError(func, WSAGetLastError());
}
struct WSAInit
{
WSAInit()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
// std::cout << "iResult : " << iResult << endl;
if (iResult != 0)
winsockError("WSAStartup", iResult);
}
~WSAInit()
{
WSACleanup();
}
};
struct Socket
{
SOCKET sckt;
Socket(SOCKET sock) : sckt(sock)
{
}
Socket(int family, int socktype, int protocol)
{
sckt = socket(family, socktype, protocol);
if (sckt == INVALID_SOCKET)
winsockError("socket");
}
~Socket()
{
Close();
}
void Close()
{
if (sckt != INVALID_SOCKET)
{
closesocket(sckt);
sckt = INVALID_SOCKET;
}
}
void Bind(sockaddr *addr, int addrlen)
{
if (bind(sckt, addr, addrlen) == SOCKET_ERROR)
winsockError("bind");
}
void Listen(int Backlog)
{
if (listen(sckt, Backlog) == SOCKET_ERROR)
winsockError("listen");
}
void Accept(sockaddr *addr, int addrlen, Socket &sock)
{
sock = accept(sckt, addr, addrlen);
if (!sock)
winsockError("accept");
}
void Read(void *buff, int buflen)
{
char *pbuf = reinterpret_cast<char*>(buff);
int bytes_read;
while (buflen > 0)
{
bytes_read = recv(sckt, pbuf, buflen, 0);
if (bytes_read == SOCKET_ERROR)
winsockError("recv");
if (bytes_read == 0)
throw std::runtime_error("client disconnected");
pbuf += bytes_read;
buflen -= bytes_read;
}
}
void Shutdown(int which)
{
if (shutdown(sckt, which) == SOCKET_ERROR)
winsockError("shutdown");
}
bool operator !() const
{
return (sckt == INVALID_SOCKET);
}
Socket& operator =(SOCKET sock)
{
Close();
sckt = sock;
return *this;
}
};
struct AddrInfo
{
addrinfo *ai;
AddrInfo() : ai(NULL) {}
~AddrInfo()
{
if (ai)
freeaddrinfo(ai);
}
addrinfo* operator->() { return ai; }
addrinfo** operator&() { return &ai; }
};
int __cdecl main(void)
{
try
{
// Initialize Winsock
WSAInit wsa;
// Resolve the server address and port
addrinfo hints = {0};
AddrInfo result;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
int iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
//std::cout << "again :iResult : " << iResult << std::endl;
if (iResult != 0)
winsockError("getaddrinfo", iResult);
// Create a SOCKET for listening for client
Socket ListenSocket(result->ai_family, result->ai_socktype, result->ai_protocol);
// Setup the listening socket
ListenSocket.Bind(result->ai_addr, (int)result->ai_addrlen);
// start listening
ListenSocket.Listen(1);
// Accept a client socket
Socket ClientSocket;
ListenSocket.Accept(NULL, 0, ClientSocket);
std::cout << "client connected" << std::endl;
// Receive until the peer sends a file or shuts down the connection
unsigned long FileSize;
ClientSocket.Read(&FileSize, sizeof(FileSize));
FileSize = ntohl(FileSize);
std::cout << "File size: " << FileSize << std::endl;
std::ofstream File("F:\\file2.txt" std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
if (!File)
throw std::runtime_error("ofstream failed with error");
if (FileSize > 0)
{
char Buffer[1024];
int bytes_to_read;
do
{
bytes_to_read = std::min(FileSize, sizeof(Buffer));
ClientSocket.Read(Buffer, bytes_to_read);
if (!File.write(Buffer, bytes_to_read))
throw std::runtime_error("write failed with error");
FileSize -= bytes_to_read;
}
while (FileSize > 0);
}
File.close();
std::cout << "file received" << std::endl;
ClientSocket.Shutdown(SD_BOTH);
}
catch (const std::exception &e)
{
std::cout << e.what() << std::endl;
return 1;
}
std::cin.get();
return 0;
}
客户:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <algorithm>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_PORT "1234"
void winsockError(const char *func, int errcode)
{
std::ostringstream oss;
oss << func << " failed with error: " << errcode;
throw std::runtime_error(oss.str());
}
void winsockError(const char *func)
{
winsockError(func, WSAGetLastError());
}
struct WSAInit
{
WSAInit()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
// std::cout << "iResult : " << iResult << std::endl;
if (iResult != 0)
winsockError("WSAStartup", iResult);
}
~WSAInit()
{
WSACleanup();
}
};
struct Socket
{
SOCKET sckt;
Socket() : sckt(INVALID_SOCKET) {}
Socket(SOCKET sock) : sckt(sock) {}
~Socket()
{
Close();
}
void Create(int family, int socktype, int protocol)
{
Close();
sckt = socket(family, socktype, protocol);
if (sckt == INVALID_SOCKET)
winsockError("socket");
}
void Close()
{
if (sckt != INVALID_SOCKET)
{
closesocket(sckt);
sckt = INVALID_SOCKET;
}
}
bool Connect(sockaddr *addr, int addrlen)
{
return (connect(sckt, addr, addrlen) != SOCKET_ERROR);
}
void Send(void *buff, int buflen)
{
char *pbuf = reinterpret_cast<char*>(buff);
int bytes_sent;
while (buflen > 0)
{
bytes_sent = send(sckt, pbuf, buflen, 0);
if (bytes_sent == SOCKET_ERROR)
winsockError("send");
if (bytes_sent == 0)
throw std::runtime_error("client disconnected");
pbuf += bytes_sent;
buflen -= bytes_sent;
}
}
void Shutdown(int which)
{
if (shutdown(sckt, which) == SOCKET_ERROR)
winsockError("shutdown");
}
bool operator !() const { return (sckt == INVALID_SOCKET); }
};
struct AddrInfo
{
addrinfo *ai;
AddrInfo() : ai(NULL) {}
~AddrInfo()
{
if (ai)
freeaddrinfo(ai);
}
addrinfo* operator->() { return ai; }
addrinfo** operator&() { return &ai; }
};
int __cdecl main(int argc, char **argv)
{
try
{
// Validate the parameters
if (argc != 2)
{
std::ostringstream oss;
oss << "usage: " << argv[0] << " server-name";
throw std::runtime_error(oss.str());
}
// Initialize Winsock
WSAInit wsa;
addrinfo hints = {0};
AddrInfo result;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
int iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if (iResult != 0)
winsockError("getaddrinfo", iResult);
// Attempt to connect to an address until one succeeds
Socket ConnectSocket;
for(addrinfo *ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
// Create a SOCKET for connecting to server
ConnectSocket.Create(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
// Connect to server.
if (ConnectSocket.Connect(ptr->ai_addr, (int)ptr->ai_addrlen))
break;
ConnectSocket.Close();
}
if (!ConnectSocket)
throw std::runtime_error("Unable to connect to server!");
//Send A File ///
std::ifstream File("E:\\file1.txt", std::ios_base::in | std::ios_base::binary);
if (!File)
throw std::runtime_error("ifstream failed with error");
File.seekg(0, std::ios_base::end);
if (!File)
throw std::runtime_error("seekg failed with error");
unsigned long FileSize = File.tellg();
if (!File)
throw std::runtime_error("tellg() failed with error");
//std::cout << "file size is " << FileSize << std::endl;
File.seekg(0, ios_base::beg);
if (!File)
throw std::runtime_error("seekg failed with error");
unsigned long tmpFileSize = htonl(FileSize);
ConnectSocket.Send(&tmpFileSize, sizeof(tmpFileSize));
if (FileSize > 0)
{
char Buffer[1024];
int bytes_to_send;
do
{
bytes_to_send = std::min(FileSize, sizeof(Buffer));
if (!File.read(Buffer, bytes_to_send))
throw std::runtime_error("read failed with error");
ConnectSocket.Send(Buffer, bytes_to_send);
FileSize -= bytes_to_send;
}
while (FileSize > 0);
}
File.close();
std::cout << "file sent" << std::endl;
// shutdown the connection since no more data will be sent
ConnectSocket.Shutdown(SD_BOTH);
}
catch (const std::exception &e)
{
std::cout << e.what() << std::endl;
return 1;
}
std::cin.get();
return 0;
}