138 linhas
2.6 KiB
C++
138 linhas
2.6 KiB
C++
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#ifdef __WIN32
|
|
#include <winsock2.h>
|
|
#else
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
|
|
#include "socket.h"
|
|
#include "logoutput.h"
|
|
|
|
#ifdef __WIN32
|
|
bool wsaStartupDone = false;
|
|
#endif
|
|
|
|
ClientSocket::ClientSocket()
|
|
{
|
|
sockfd = -1;
|
|
|
|
#ifdef __WIN32
|
|
if (!wsaStartupDone)
|
|
{
|
|
WSADATA wsaData;
|
|
memset(&wsaData, 0, sizeof(WSADATA));
|
|
//WSAStartup needs to be called on windows before sockets can be used. Request version 1.1, which is supported on windows 98 and higher.
|
|
WSAStartup(MAKEWORD(1, 1), &wsaData);
|
|
wsaStartupDone = true;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void ClientSocket::connectTo(std::string host, int port)
|
|
{
|
|
struct sockaddr_in serv_addr;
|
|
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
memset(&serv_addr, '0', sizeof(serv_addr));
|
|
serv_addr.sin_family = AF_INET;
|
|
serv_addr.sin_port = htons(port);
|
|
serv_addr.sin_addr.s_addr = inet_addr(host.c_str());
|
|
|
|
if (connect(sockfd, reinterpret_cast<struct sockaddr*>(&serv_addr), sizeof(serv_addr)) < 0)
|
|
{
|
|
printf("Connect to %s:%d failed\n", host.c_str(), port);
|
|
close();
|
|
return;
|
|
}
|
|
}
|
|
|
|
ClientSocket::~ClientSocket()
|
|
{
|
|
close();
|
|
}
|
|
|
|
void ClientSocket::sendInt32(int32_t nr)
|
|
{
|
|
sendAll(&nr, sizeof(int32_t));
|
|
}
|
|
|
|
void ClientSocket::sendFloat32(float f)
|
|
{
|
|
sendAll(&f, sizeof(float));
|
|
}
|
|
|
|
|
|
void ClientSocket::sendAll(const void* data, int length)
|
|
{
|
|
if (sockfd == -1)
|
|
return;
|
|
const char* ptr = static_cast<const char*>(data);
|
|
while(length > 0)
|
|
{
|
|
int n = send(sockfd, ptr, length, 0);
|
|
if (n <= 0)
|
|
{
|
|
close();
|
|
return;
|
|
}
|
|
ptr += length;
|
|
length -= n;
|
|
}
|
|
}
|
|
|
|
int32_t ClientSocket::recvInt32()
|
|
{
|
|
int32_t ret = -1;
|
|
recvAll(&ret, sizeof(int32_t));
|
|
return ret;
|
|
}
|
|
|
|
float ClientSocket::recvFloat32()
|
|
{
|
|
float ret = 0;
|
|
recvAll(&ret, sizeof(float));
|
|
return ret;
|
|
}
|
|
|
|
void ClientSocket::recvAll(void* data, int length)
|
|
{
|
|
if (sockfd == -1)
|
|
return;
|
|
char* ptr = static_cast<char*>(data);
|
|
while(length > 0)
|
|
{
|
|
int n = recv(sockfd, ptr, length, 0);
|
|
if (n == 0)
|
|
{
|
|
close();
|
|
return;
|
|
}
|
|
if (n < 0)
|
|
{
|
|
cura::logError("ClientSocket::recvAll error...");
|
|
close();
|
|
return;
|
|
}
|
|
ptr += n;
|
|
length -= n;
|
|
}
|
|
}
|
|
|
|
void ClientSocket::close()
|
|
{
|
|
if (sockfd == -1)
|
|
return;
|
|
#ifdef __WIN32
|
|
closesocket(sockfd);
|
|
#else
|
|
::close(sockfd);
|
|
#endif
|
|
sockfd = -1;
|
|
}
|