1/*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include <sstream>
16#include <cstring>
17#include <sys/socket.h>
18#include <arpa/inet.h>
19#include <unistd.h>
20#include "include/sp_server_socket.h"
21#include "include/sp_log.h"
22namespace OHOS {
23namespace SmartPerf {
24SpServerSocket::SpServerSocket() : sockPort(0) {}
25
26SpServerSocket::~SpServerSocket()
27{
28    Close();
29}
30
31int SpServerSocket::Init(ProtoType type)
32{
33    if (type == ProtoType::TCP) {
34        sock = socket(AF_INET, SOCK_STREAM, 0);
35        sockPort = tcpPort;
36    }
37    if (type == ProtoType::UDP || type == ProtoType::UDPEX) {
38        sock = socket(AF_INET, SOCK_DGRAM, 0);
39        sockPort = (type == ProtoType::UDP ? udpPort : udpExPort);
40    }
41    if (sock < 0) {
42        LOGE("SpServerSocket::Init Socket Create Failed");
43        return -1;
44    }
45    if (type == ProtoType::TCP) {
46        int optval = 1;
47        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
48            LOGE("SpServerSocket::Init Socket Setsockopt failed prot(%d)", sockPort);
49            return -1;
50        }
51    }
52    local.sin_family = AF_INET;
53    local.sin_port = htons(sockPort);
54    local.sin_addr.s_addr = inet_addr("127.0.0.1");
55    if (::bind(sock, reinterpret_cast<struct sockaddr *>(&local), sizeof(local)) < 0) {
56        LOGE("SpServerSocket::Init Socket Bind failed prot(%d)", sockPort);
57        return -1;
58    }
59    if (type == ProtoType::TCP) {
60        if (listen(sock, listenCount) < 0) {
61            LOGE("SpServerSocket::Init Socket Listen failed");
62            return -1;
63        }
64    }
65
66    LOGI("SpServerSocket::Init OK,prot(%d)", sockPort);
67    return 0;
68}
69
70int SpServerSocket::Accept()
71{
72    connFd = accept(sock, nullptr, nullptr);
73    return connFd;
74}
75
76int SpServerSocket::Sendto(std::string &sendBuf)
77{
78    socklen_t len = sizeof(sockaddr_in);
79    sendto(sock, sendBuf.c_str(), sendBuf.size(), 0, reinterpret_cast<struct sockaddr *>(&client), len);
80    return 0;
81}
82
83int SpServerSocket::Send(const std::string &sendBuf) const
84{
85    int sendBytes = send(connFd, sendBuf.c_str(), sendBuf.size(), 0);
86    if (sendBytes < 0) {
87        LOGE("SpServerSocket::Send Error(%d) fd(%d)", sendBytes, connFd);
88        return -1;
89    }
90    return 0;
91}
92
93void SpServerSocket::Close()
94{
95    int optval = 1;
96    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
97    local.sin_family = AF_INET;
98    local.sin_port = htons(sockPort);
99    local.sin_addr.s_addr = inet_addr("127.0.0.1");
100    if (::bind(sock, reinterpret_cast<struct sockaddr *>(&local), sizeof(local)) < 0) {
101        LOGI("SpServerSocket::Init Socket Bind failed");
102    }
103}
104
105int SpServerSocket::Recvfrom()
106{
107    bzero(rbuf, sizeof(rbuf));
108    socklen_t len = sizeof(sockaddr_in);
109    int l = recvfrom(sock, rbuf, sizeof(rbuf) - 1, 0, reinterpret_cast<struct sockaddr *>(&client), &len);
110    if (l > 0) {
111        std::cout << "Client:" << rbuf << std::endl;
112    }
113    return l;
114}
115
116int SpServerSocket::Recv()
117{
118    bzero(rbuf, sizeof(rbuf));
119    int l = recv(connFd, rbuf, sizeof(rbuf) - 1, 0);
120    if (l > 0) {
121        std::cout << "Client:" << rbuf << std::endl;
122    } else {
123        LOGE("SpServerSocket::recv Error(%d) fd(%d)", l, connFd);
124        return -1;
125    }
126    return l;
127}
128
129std::string SpServerSocket::RecvBuf() const
130{
131    std::string recvBuf = rbuf;
132    return recvBuf;
133}
134}
135}
136