NetCpp/src/socket.cpp
2019-12-12 22:34:09 +08:00

287 lines
7.3 KiB
C++

//
// socket.cpp
// Net
//
// Created by 胡一兵 on 2019/1/17.
// Copyright © 2019年 Bakantu. All rights reserved.
//
#include "memory.h"
#include "net.h"
void SocketClient::SetSendPort(int port){
send_addr.SetPort(port);
}
void SocketClient::SetSendIP(string ip){
send_addr.SetIP(ip);
}
ssize_t SocketTCPCServer::Recv(string &str){
ssize_t bdtas = 0 ,tmp_bdtas;
while ((tmp_bdtas = read(data_sfd, buff, BUFSIZ)) > 0) {
str += string(buff,tmp_bdtas);
bdtas += tmp_bdtas;
}
return bdtas;
}
int SocketTCPCServer::Listen(void){
return listen(server_sfd, 10);
}
void SocketTCPClient::Send(string str){
ssize_t len = send(client_sfd,str.data(),str.size(),0);
if(len != str.size()) throw "size unmatch";
}
ssize_t SocketUDPServer::Recv(string &str){
ssize_t tlen;
// 非阻塞接收
if(set_fcntl){
tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, server_addr.RawObj(), server_addr.SizeP());
// 读取错误
if(tlen == -1 && errno != EAGAIN) return -1;
// 缓冲区没有信息
else if(tlen == 0 || (tlen == -1 && errno == EAGAIN)) return 0;
// 成功读取信息
else{
str = buff;
buff[tlen] = '\0';
return 1;
}
}
// 阻塞接收
else{
tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, server_addr.RawObj(), server_addr.SizeP());
if(~tlen){
str = buff;
buff[tlen] = '\0';
return 1;
}
else return -1;
}
}
ssize_t SocketUDPServer::RecvRAW(char **p_rdt, Addr &taddr){
ssize_t tlen;
sockaddr_in tsai;
socklen_t tsai_size = sizeof(sockaddr);
// 非阻塞读取
if(set_fcntl){
tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, (struct sockaddr *)(&tsai), &tsai_size);
//读取错误
if(tlen == -1 && errno != EAGAIN){
*p_rdt = nullptr;
printf("%d",errno);
perror("recv");
return -1;
}
//缓冲区没有信息
else if(tlen == 0 || (tlen == -1 && errno == EAGAIN)){
*p_rdt = nullptr;
return 0;
}
//成功读取信息
else{
*p_rdt = (char *)malloc(tlen);
taddr.SetSockAddr(tsai);
memcpy(*p_rdt, buff, tlen);
return tlen;
}
}
else{
tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, server_addr.RawObj(), server_addr.SizeP());
if(~tlen){
*p_rdt = (char *)malloc(tlen);
memcpy(p_rdt, buff, tlen);
return tlen;
}
else{
*p_rdt = nullptr;
return -1;
}
}
}
void SocketUDPServer::UDPSetFCNTL(void){
int flags = fcntl(server_sfd, F_GETFL, 0);
fcntl(server_sfd, F_SETFL, flags | O_NONBLOCK);
set_fcntl = true;
}
void SocketUDPClient::Send(string buff){
sendto(client_sfd, buff.data(), buff.size(), 0, send_addr.RawObj(), send_addr.Size());
}
ssize_t SocketUDPClient::SendRAW(char *buff, unsigned long size){
return sendto(client_sfd, buff, size, 0, send_addr.RawObj(), send_addr.Size());
}
ssize_t SocketTCPClient::SendRAW(char *buff, unsigned long size){
//对于长数据进行分段发送
if (size > 1023) {
ssize_t idx = 0, nidx = 0;
Byte vbuff[1024], gbuff[1024];
while (idx < size-1) {
if (!idx) memcpy(vbuff, "DSAT", sizeof(uint32_t));
else memcpy(vbuff, "DCST", sizeof(uint32_t));
if (idx + 1000 < size - 1) {
nidx = idx + 1000;
memcpy(vbuff + sizeof(uint32_t) + nidx - idx + 1, "DCTN", sizeof(uint32_t));
}
else {
nidx = size - 1;
memcpy(vbuff + sizeof(uint32_t) + nidx - idx + 1, "DFSH", sizeof(uint32_t));
}
memcpy(vbuff + sizeof(uint32_t), buff + idx, nidx - idx + 1);
send(client_sfd, vbuff, 2 * sizeof(uint32_t) + nidx - idx + 1, 0);
ssize_t grtn = recv(client_sfd, gbuff, BUFSIZ,0);
if (grtn > 0 && !memcmp(gbuff, "DGET", sizeof(uint32_t)));
else {
return -1;
}
idx = nidx + 1;
}
return size;
}
else {
ssize_t send_size = send(client_sfd, buff, size, 0);
return send_size;
}
}
void SocketClient::SetSendSockAddr(struct sockaddr_in tsi){
send_addr.SetSockAddr(tsi);
}
void SocketTCPClient::Close(void){
close(client_sfd);
}
//长连接数据接收
ssize_t SocketTCPCServer::RecvRAW_SM(char **p_rdt, Addr &taddr){
ssize_t bdtas = 0, tmp_bdtas;
*p_rdt = nullptr;
bool dsat = false, dfsh = false, if_signal = false;
while (!dfsh && (tmp_bdtas = recv(data_sfd, buff, BUFSIZ, 0)) > 0) {
if (!memcmp(buff, "NETC", sizeof(uint32_t))) {
dsat = true;
dfsh = true;
if_signal = true;
}
if (!memcmp(buff, "DSAT", sizeof(uint32_t))) dsat = true;
if (!memcmp(buff+tmp_bdtas-sizeof(uint32_t), "DFSH", sizeof(uint32_t))) dfsh = true;
if (dsat) {
send(data_sfd, "DGET", sizeof(uint32_t), 0);
if (*p_rdt == nullptr) {
if (if_signal) {
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
bdtas += tmp_bdtas;
continue;
}
*p_rdt = (char *)malloc(tmp_bdtas - 2 * sizeof(uint32_t));
memcpy(*p_rdt, buff + sizeof(uint32_t), tmp_bdtas - 2 * sizeof(uint32_t));
}
else {
*p_rdt = (char *)realloc(*p_rdt, bdtas + tmp_bdtas - 2 * sizeof(uint32_t));
memcpy(*p_rdt + bdtas, buff + sizeof(uint32_t), tmp_bdtas - 2 * sizeof(uint32_t));
}
}
bdtas += tmp_bdtas;
}
return bdtas;
}
//短连接数据接收
ssize_t SocketTCPCServer::RecvRAW(char **p_rdt, Addr &taddr){
ssize_t bdtas = 0 ,tmp_bdtas;
*p_rdt = nullptr;
while ((tmp_bdtas = recv(data_sfd, buff, BUFSIZ, 0)) > 0) {
if(*p_rdt == nullptr){
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
}
else{
*p_rdt = (char *)realloc(*p_rdt, bdtas + tmp_bdtas);
memcpy(*p_rdt + bdtas, buff, tmp_bdtas);
}
bdtas += tmp_bdtas;
}
return bdtas;
}
void SocketTCPCServer::Accept(void ){
data_sfd = accept(server_sfd, client_addr.RawObj(), client_addr.SizeP());
}
void SocketTCPClient::Reconnect(void){
client_sfd = socket(ipptl,SOCK_STREAM,0);
if(!~client_sfd) throw "fail to get client sfd";
if(!~connect(client_sfd,send_addr.RawObj(),send_addr.Size())) throw "fail to connect";
}
void SocketTCPCServer::CloseConnection(void){
close(data_sfd);
}
void SocketTCPCServer::Close(void) {
shutdown(server_sfd, SHUT_RDWR);
}
void SocketTCPClient::GetRespond(string &str){
ssize_t size = recv(client_sfd, buff, BUFSIZ, 0);
if(size > 0){
str = string(buff,size);
}
else str = "";
}
void SocketTCPCServer::SendRespond(string &str){
send(data_sfd, str.data(), str.size(), 0);
}
ssize_t SocketTCPClient::RecvRAW(char **p_rdt, Addr &taddr){
ssize_t tmp_bdtas = recv(client_sfd, buff, BUFSIZ, 0);
if (tmp_bdtas > 0) {
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
}
return tmp_bdtas;
}
Addr &SocketTCPClient::GetAddr(void){
return send_addr;
}
void SocketTCPClient::SetAddr(Addr &taddr){
send_addr = taddr;
}
Addr &SocketTCPCServer::GetAddr(void){
return server_addr;
}
Addr &SocketTCPCServer::GetClientAddr(void){
return client_addr;
}
int SocketTCPCServer::GetDataSFD(void){
return data_sfd;
}
void SocketTCPCServer::SetDataSFD(int tdata_sfd){
data_sfd = tdata_sfd;
}
void SocketTCPCServer::SetClientAddr(Addr &caddr){
client_addr = caddr;
}