Skip to content

Instantly share code, notes, and snippets.

@boxdot
Created June 13, 2016 22:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boxdot/9637e24be7a51fc4c2add1291f6a4ca8 to your computer and use it in GitHub Desktop.
Save boxdot/9637e24be7a51fc4c2add1291f6a4ca8 to your computer and use it in GitHub Desktop.
Simple socket example in OSX
// Compile with:
// c++ -std=c++11 socket.cpp -o socket
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <vector>
#include <iostream>
template <typename Condition>
void check_syscall(Condition cond, const std::string& errmsg) {
if (!cond) {
throw std::runtime_error(errmsg + ": " + strerror(errno));
}
}
void server() {
int server_fd = socket(PF_INET, SOCK_STREAM, 0);
check_syscall(server_fd != -1, "cannot create socket");
struct sockaddr_in server_addr = {
sizeof(struct sockaddr_in), AF_INET, htons(8080), {INADDR_ANY}};
check_syscall(
bind(server_fd, (struct sockaddr*) &server_addr,sizeof(server_addr))
!= -1,
"cannot assign an address");
check_syscall(listen(server_fd, 16) != -1, "cannot listen on socket");
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_fd = accept(
server_fd, (struct sockaddr*) &client_addr, &client_addr_len);
check_syscall(client_fd != -1, "cannot accept new connections");
std::vector<char> buffer(1024, 0);
char* pos = buffer.data();
while (auto bytes = read(client_fd, pos, 1024)) {
check_syscall(bytes != -1, "cannot read from client");
if (bytes == 1024) {
buffer.resize(buffer.size() + 1024);
pos += 1024;
} else {
buffer.resize(pos + bytes - buffer.data());
}
}
std::string message(buffer.begin(), buffer.end());
std::cerr << "Received message: " << message.c_str() << std::endl;
close(client_fd);
close(server_fd);
}
void client() {
int fd = socket(AF_INET, SOCK_STREAM, 0);
check_syscall(fd != -1, "cannot create socket");
struct sockaddr_in server_addr = {
sizeof(struct sockaddr_in), AF_INET, htons(8080), {INADDR_ANY}};
check_syscall(
connect(fd, (struct sockaddr*) &server_addr, sizeof(server_addr))
!= -1,
"cannot connect to server");
std::string message = "Hello from the client!";
int bytes = write(fd, message.data(), message.size());
check_syscall(bytes, "cannot write data to socket");
close(fd);
}
void usage(const char* program) {
std::cerr << "Usage: " << program << " <server|client>" << std::endl;
}
int main(int argc, char const *argv[])
{
if (argc != 2) {
usage(argv[0]);
return 1;
}
std::string mode{argv[1]};
if (mode == "server") {
server();
} else if (mode == "client") {
client();
} else {
usage(argv[0]);
return 1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment