Last active
August 29, 2015 14:23
-
-
Save makotoshimazu/314d8dab97a5092bcfe9 to your computer and use it in GitHub Desktop.
send/recv
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
//! gcc -o skype_simple_serv.bin skype_simple_serv.c -W -Wall -O3 -std=gnu99 | |
/* | |
* skype_simple_serv.c | |
* | |
* Author: Makoto Shimazu <[email protected]> | |
* URL: https://amiq11.tumblr.com | |
* License: MIT License | |
* Created: 2015-06-22 | |
* | |
*/ | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <netinet/ip.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
const int kBufferSize = 8820; /* 100ms = 2(byte/sample) * 44100 * 0.1 */ | |
enum behavior { | |
SERVER, | |
CLIENT, | |
}; | |
enum task { | |
SEND, | |
RECEIVE | |
}; | |
void usage(const char *filepath) { | |
fprintf(stderr, "Usage: %s [ip] port\n", filepath); | |
} | |
void die(const char *message) { | |
perror(message); | |
exit(EXIT_FAILURE); | |
} | |
int prepareSocketServer(int port) { | |
int s = socket(PF_INET, SOCK_STREAM, 0); | |
struct sockaddr_in addr; | |
addr.sin_family = AF_INET; | |
addr.sin_addr.s_addr = INADDR_ANY; | |
addr.sin_port = htons(port); | |
if (bind(s, (struct sockaddr *)&addr, sizeof(addr))) { | |
perror("bind"); | |
close(s); | |
return -1; | |
} | |
if (listen(s, 10)) { | |
perror("listen"); | |
close(s); | |
return -1; | |
} | |
struct sockaddr_in client_addr; | |
socklen_t socklen = sizeof(client_addr); | |
int ss; | |
if ((ss = accept(s, (struct sockaddr *)&client_addr, &socklen)) < 0) { | |
perror("accept"); | |
close(s); | |
return -1; | |
} | |
fprintf(stderr, "connected!\n"); | |
return ss; | |
} | |
int prepareSocketClient(const char *ip, int port) { | |
int s = socket(PF_INET, SOCK_STREAM, 0); | |
if (s < 0) | |
die("socket"); | |
struct sockaddr_in addr; | |
addr.sin_family = AF_INET; | |
addr.sin_addr.s_addr = inet_addr(ip); | |
addr.sin_port = htons(port); | |
if (connect(s, (struct sockaddr *)&addr, sizeof(addr))) { | |
perror("connect"); | |
return -1; | |
} | |
return s; | |
} | |
int prepareSocket(enum behavior behavior, const char *ip_address, int port) { | |
int socket_id = -1; | |
if (behavior == SERVER) { | |
printf("Server\n"); | |
socket_id = prepareSocketServer(port); | |
} else if (behavior == CLIENT) { | |
printf("Client\n"); | |
socket_id = prepareSocketClient(ip_address, port); | |
} | |
return socket_id; | |
} | |
int readNBytes(int fd, uint8_t *buffer, int length) { | |
int received = 0; | |
int n; | |
while (received < length) { | |
if ((n = read(fd, &buffer[received], length - received)) < 0) { | |
perror("read"); | |
return -1; | |
} | |
received += n; | |
} | |
return received; | |
} | |
int writeNBytes(int fd, uint8_t *buffer, int length) { | |
int sent = 0; | |
int n; | |
while (sent < length) { | |
if ((n = write(fd, &buffer[sent], length - sent)) < 0) { | |
perror("write"); | |
return -1; | |
} | |
sent += n; | |
} | |
return sent; | |
} | |
int main(int argc, const char * const argv[]) { | |
/* Prepare variables from the arguments */ | |
enum behavior behavior; | |
const char *ip_address; | |
int port; | |
if (argc == 2) { | |
behavior = SERVER; | |
port = atoi(argv[1]); | |
ip_address = NULL; | |
} else if (argc == 3) { | |
behavior = CLIENT; | |
ip_address = argv[1]; | |
port = atoi(argv[2]); | |
} else { | |
usage(argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
/* Prepare socket_id */ | |
int socket_id = prepareSocket(behavior, ip_address, port); | |
if (socket_id < 0) { | |
exit(EXIT_FAILURE); | |
} | |
/* send/Rev */ | |
uint8_t buffer[kBufferSize]; | |
enum task task = (behavior == SERVER) ? RECEIVE : SEND; | |
while(1) { | |
if (task == SEND) { | |
int n = fread(buffer, sizeof(uint8_t), kBufferSize, stdin); | |
int rc = writeNBytes(socket_id, buffer, n); | |
if (rc < 0) | |
exit(EXIT_FAILURE); | |
task = RECEIVE; | |
} else if (task == RECEIVE) { | |
int n = readNBytes(socket_id, buffer, kBufferSize); | |
int rc = fwrite(buffer, sizeof(uint8_t), n, stdout); | |
if (rc < 0) | |
exit(EXIT_FAILURE); | |
task = SEND; | |
} | |
} | |
close(socket_id); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment