Created
June 13, 2016 22:20
-
-
Save boxdot/9637e24be7a51fc4c2add1291f6a4ca8 to your computer and use it in GitHub Desktop.
Simple socket example in OSX
This file contains 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 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