-
-
Save MyelinsheathXD/1dfd0331fb4da9953b54a44eb6b52d2e to your computer and use it in GitHub Desktop.
Send a numpy array via socket to a C/C++ program.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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