Skip to content

Instantly share code, notes, and snippets.

@MyelinsheathXD
Forked from mlaves/client.py
Created April 15, 2024 13:20
Show Gist options
  • Save MyelinsheathXD/1dfd0331fb4da9953b54a44eb6b52d2e to your computer and use it in GitHub Desktop.
Save MyelinsheathXD/1dfd0331fb4da9953b54a44eb6b52d2e to your computer and use it in GitHub Desktop.
Send a numpy array via socket to a C/C++ program.
import socket
import numpy as np
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65432 # The port used by the server
data = np.random.rand(1000000)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print(f"Sent {np.prod(data.shape)} elements.")
s.connect((HOST, PORT))
print(data.ravel()[-1])
# data length descriptor as uint32
length_descriptor = np.uint32(np.prod(data.shape)).tobytes(order='C')
# payload as C-style float32 byte array
payload = data.astype(np.float32).tobytes(order='C')
s.sendall(length_descriptor + payload)
// compile with `c++ -std=c++11 server.cpp -o server`
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <vector>
#define PORT 65432
int main()
{
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
while(true)
{
std::cout << "Waiting for incoming connection...\n";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen)) < 0)
{
perror("accept");
exit(EXIT_FAILURE);
}
std::cout << "Connected by " << inet_ntoa(address.sin_addr) << "\n";
// receive 4 bytes for length indicator
int bytes_length_count = 0;
int bytes_length_total = 0;
uint32_t length_descriptor = 0;
char* len_buffer = reinterpret_cast<char*>(&length_descriptor);
while (bytes_length_total < 4)
{
bytes_length_count = recv(new_socket,
&len_buffer[bytes_length_total],
sizeof (uint32_t) - bytes_length_total,
0);
if (bytes_length_count == -1)
{
perror("recv");
}
else if (bytes_length_count == 0)
{
std::cout << "Unexpected end of transmission." << std::endl;
close(server_fd);
exit(EXIT_SUCCESS);
}
bytes_length_total += bytes_length_count;
}
std::cout << "Receiving " << length_descriptor << " elements.\n";
// receive payload
int bytes_payload_count = 0;
int bytes_payload_total = 0;
size_t data_size = length_descriptor*sizeof(float);
std::vector<float> data(length_descriptor);
char* buffer = reinterpret_cast<char*>(&data[0]);
while (bytes_payload_total < static_cast<int>(data_size))
{
bytes_payload_count = recv(new_socket,
&buffer[bytes_payload_total],
data_size - bytes_payload_total,
0);
if (bytes_payload_count == -1)
{
perror("recv");
}
else if (bytes_payload_count == 0)
{
std::cout << "Unexpected end of transmission" << std::endl;
close(server_fd);
exit(EXIT_SUCCESS);
}
bytes_payload_total += bytes_payload_count;
}
// print out last element as sanity check
std::cout << data[length_descriptor-1] << std::endl;
// close socket
close(server_fd);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment