Chào mọi người, em mới học viết socket trong c++, em có viết thử 1 cái server để giao tiếp với client bằng python. Em làm theo hướng dẫn trên mạng nhưng mà nó cứ bị lỗi ở bước ::recv(), mọi người xem giúp em ạ. Cảm ơn mọi người.
unix_server.h
#ifndef __UNIX_SERVER__
#define __UNIX_SERVER__
#include <sys/un.h>
#include <string>
#define DEFAULT_SOCKET "/tmp/server_.sock"
#define BACKLOG_SIZE 100
#define BUFF_LENGTH 8
class UnixServer {
private:
struct sockaddr_un sock_addr;
int csock_fd;
int dsock_fd;
char * buff;
static UnixServer * m_instance;
ssize_t AppendSizeToBuffer(char* buff, int val);
ssize_t AppendStringToBuffer(char* buff, std::string& val);
UnixServer();
~UnixServer();
public:
static UnixServer * Instance();
bool Open();
bool Close();
bool HandleRecvQuery();
};
#endif //__UNIX_SERVER__
unix_server.cpp
#include <sys/socket.h>
#include <string.h>
#include "unix_server.h"
#include "logger.h"
UnixServer *
UnixServer::m_instance = NULL;
UnixServer::UnixServer() {
}
UnixServer::~UnixServer() {
}
ssize_t
UnixServer::AppendSizeToBuffer(char* buff, int val) {
memcpy(buff, &val, sizeof(val));
return sizeof(val);
}
ssize_t
UnixServer::AppendStringToBuffer(char* buff, std::string& val) {
ssize_t len = AppendSizeToBuffer(buff, val.length());
memcpy(buff + len, val.c_str(), val.length());
return len + val.length();
}
UnixServer *
UnixServer::Instance() {
if (m_instance == NULL) {
m_instance = new UnixServer();
}
return m_instance;
}
bool
UnixServer::Open() {
int ret;
csock_fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
if (csock_fd < 0) {
LogError << "socket";
return false;
}
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sun_family = AF_UNIX;
strncpy(sock_addr.sun_path, DEFAULT_SOCKET, sizeof(sock_addr.sun_path) - 1);
ret = ::bind(csock_fd, (const struct sockaddr *)& sock_addr, sizeof(sock_addr));
if (ret < 0) {
LogError << "bind";
return false;
}
ret = ::listen(csock_fd, BACKLOG_SIZE);
if (ret < 0) {
LogError << "listen";
return false;
}
return true;
}
bool
UnixServer::Close() {
::close(csock_fd);
::unlink(DEFAULT_SOCKET);
return true;
}
bool
UnixServer::HandleRecvQuery() {
dsock_fd = ::accept(csock_fd, NULL, NULL);
if (dsock_fd < 0) {
LogError << "accept";
return false;
}
ssize_t recv_size = BUFF_LENGTH;
int ret = ::setsockopt(dsock_fd, SOL_SOCKET, SO_RCVLOWAT, (char*)&recv_size, sizeof(recv_size));
if (ret < 0) {
LogError << "setsockopt";
return false;
}
ret = ::recv(dsock_fd, buff, recv_size, 0);
if (ret < 0) {
LogError << "recv";
return false;
}
if (ret < recv_size) {
LogError << "Client closed connection before sent all data";
return false;
}
char * buff_ptr = (char *)buff;
std::string send_data = "client got result";
ssize_t send_buff_byte = AppendStringToBuffer(buff_ptr, send_data);
ret = ::send(dsock_fd, buff, send_buff_byte, 0);
if (ret < 0) {
LogError << "send";
return false;
}
::close(dsock_fd);
return true;
}
main.cpp
#include "unix_server.h"
int main()
{
bool ret_ok = UnixServer::Instance()->Open();
if (ret_ok) {
while (true) {
ret_ok = UnixServer::Instance()->HandleRecvQuery();
if (!ret_ok) {
break;
}
}
}
UnixServer::Instance()->Close();
return 0;
}
client.py
import socket
import sys
import os
DEFAULT_SOCKET = '/tmp/server_.sock'
def Main():
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
print(f"connecting to {DEFAULT_SOCKET}")
try:
sock.connect(DEFAULT_SOCKET)
except:
print("Unexpected error")
try:
message = '{:032b}'.format(19999) + '{:032b}'.format(29999)
print(message.encode())
sock.sendall(message.encode())
total_recv = 0
recv = sock.recv(64)
print(recv)
expected_recv = int(float(recv))
data = ""
while total_recv != expected_recv:
data += sock.recv(expected_recv - total_recv)
total_recv += len(data)
print (data)
finally:
sock.close()
if __name__ == '__main__':
Main()