updates for 2nd video
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
out/
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
// "target": "windows-x64",
|
// "target": "windows-x64",
|
||||||
// Targets.
|
// Targets.
|
||||||
"targets": {
|
"targets": {
|
||||||
"c3hat": {
|
"client": {
|
||||||
// Executable or library.
|
// Executable or library.
|
||||||
"type": "executable",
|
"type": "executable",
|
||||||
// Additional libraries, sources
|
// Additional libraries, sources
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
module client;
|
||||||
|
import std::net;
|
||||||
|
import std::io;
|
||||||
|
|
||||||
|
const uint BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
|
fn void? sendMsg(String url, uint port, String msg) {
|
||||||
|
TcpSocket socket = tcp::connect(url, port)!;
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
while (try sent = socket.write(msg[pos:msg.len])) {
|
||||||
|
|
||||||
|
if (sent == 0) break;
|
||||||
|
|
||||||
|
pos += (int)sent;
|
||||||
|
|
||||||
|
if (sent >= msg.len) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[BUFFER_SIZE] buffer;
|
||||||
|
usz recv = socket.read(&buffer)!;
|
||||||
|
|
||||||
|
io::printfn("%s", (String)buffer[:recv]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
module client;
|
||||||
|
import std::io;
|
||||||
|
|
||||||
|
fn int main(String[] args) {
|
||||||
|
if (args.len < 4) {
|
||||||
|
io::printn("error: not enough arguments");
|
||||||
|
io::printfn("usage: %s <host> <port> <msg>", args[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
String host = args[1];
|
||||||
|
uint? port = args[2].to_uint();
|
||||||
|
if (catch err = port) {
|
||||||
|
io::printfn("couldn't convert %s to a port", args[2]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
String msg = args[3];
|
||||||
|
|
||||||
|
sendMsg(host, port, msg)!!;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
out/
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// Language version of C3.
|
||||||
|
"langrev": "1",
|
||||||
|
// Warnings used for all targets.
|
||||||
|
"warnings": [ "no-unused" ],
|
||||||
|
// Directories where C3 library files may be found.
|
||||||
|
"dependency-search-paths": [ "lib" ],
|
||||||
|
// Libraries to use for all targets.
|
||||||
|
"dependencies": [ ],
|
||||||
|
// Authors, optionally with email.
|
||||||
|
"authors": [ "John Doe <john.doe@example.com>" ],
|
||||||
|
// Version using semantic versioning.
|
||||||
|
"version": "0.1.0",
|
||||||
|
// Sources compiled for all targets.
|
||||||
|
"sources": [ "src/**" ],
|
||||||
|
// Test sources compiled for all targets.
|
||||||
|
"test-sources": [ "test/**" ],
|
||||||
|
// C sources if the project also compiles C sources
|
||||||
|
// relative to the project file.
|
||||||
|
// "c-sources": [ "csource/**" ],
|
||||||
|
// Include directories for C sources relative to the project file.
|
||||||
|
// "c-include-dirs": [ "csource/include" ],
|
||||||
|
// Build location, relative to project file.
|
||||||
|
"build-dir": "build",
|
||||||
|
// Output location, relative to project file.
|
||||||
|
"output": "build",
|
||||||
|
// Architecture and OS target.
|
||||||
|
// You can use 'c3c --list-targets' to list all valid targets.
|
||||||
|
// "target": "windows-x64",
|
||||||
|
// Targets.
|
||||||
|
"targets": {
|
||||||
|
"server": {
|
||||||
|
// Executable or library.
|
||||||
|
"type": "executable",
|
||||||
|
// Additional libraries, sources
|
||||||
|
// and overrides of global settings here.
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Global settings.
|
||||||
|
// CPU name, used for optimizations in the LLVM backend.
|
||||||
|
"cpu": "generic",
|
||||||
|
// Optimization: "O0", "O1", "O2", "O3", "O4", "O5", "Os", "Oz".
|
||||||
|
"opt": "O0"
|
||||||
|
// See resources/examples/project_all_settings.json and 'c3c --list-project-properties' to see more properties.
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
module server;
|
||||||
|
import std::io;
|
||||||
|
import std::net;
|
||||||
|
import std::collections;
|
||||||
|
|
||||||
|
fn int main(String[] args) {
|
||||||
|
String host = "localhost";
|
||||||
|
uint port = 9500;
|
||||||
|
uint backlog = 100;
|
||||||
|
|
||||||
|
startServer(host, port, backlog)!!;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
module server;
|
||||||
|
import std::io;
|
||||||
|
import std::net;
|
||||||
|
import std::collections;
|
||||||
|
import std::thread::pool;
|
||||||
|
|
||||||
|
const int BUFFSIZE = 4096;
|
||||||
|
const int THREAD_COUNT = 100;
|
||||||
|
|
||||||
|
fn void? startServer(String host, uint port, uint backlog=20) {
|
||||||
|
bool shouldQuit = false;
|
||||||
|
|
||||||
|
TcpServerSocket? server = tcp::listen(
|
||||||
|
host, port, backlog,
|
||||||
|
SocketOption.REUSEADDR,
|
||||||
|
ip_protocol: IpProtocol.IPV4);
|
||||||
|
|
||||||
|
if (catch err = server) {
|
||||||
|
io::printfn("unable to create server socket %s", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
if (catch err = server.close()) {
|
||||||
|
io::printfn("error closing socket %s", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThreadPool{THREAD_COUNT} workerPool;
|
||||||
|
if (catch err = workerPool.init()) {
|
||||||
|
io::printfn("error setting up thread pool: %s", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!shouldQuit) {
|
||||||
|
TcpSocket? client = tcp::accept(&server);
|
||||||
|
if (catch err = client) {
|
||||||
|
io::printfn("error accepting client %s", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//readInput(&client);
|
||||||
|
workerPool.push(&handleThread, &client);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn int handleThread(void *args) => @pool_init(mem, 65536) {
|
||||||
|
TcpSocket *client = (TcpSocket*)args;
|
||||||
|
readInput(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void readInput(TcpSocket *client) {
|
||||||
|
defer (void)client.close();
|
||||||
|
char[BUFFSIZE] buffer;
|
||||||
|
|
||||||
|
List{String} data;
|
||||||
|
data.init(mem);
|
||||||
|
while (try usz read = client.read(&buffer)) {
|
||||||
|
data.push((String)buffer[:read]);
|
||||||
|
if (read < BUFFSIZE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processInput(&data);
|
||||||
|
broadcast(client, &data);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void processInput(List{String} *input) {
|
||||||
|
foreach (item : input) {
|
||||||
|
io::printfn("%s", item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void broadcast(TcpSocket *socket, List{String} *messages) {
|
||||||
|
|
||||||
|
foreach (msg : messages) {
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
while (try usz sent = socket.write(msg[pos:msg.len])) {
|
||||||
|
|
||||||
|
if (sent == 0) break;
|
||||||
|
|
||||||
|
pos += (uint)sent;
|
||||||
|
|
||||||
|
if (pos >= msg.len) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-61
@@ -1,61 +0,0 @@
|
|||||||
module c3hat;
|
|
||||||
import std::io;
|
|
||||||
import std::net;
|
|
||||||
import std::collections;
|
|
||||||
|
|
||||||
fn int main(String[] args) {
|
|
||||||
String host = "localhost";
|
|
||||||
uint port = 9500;
|
|
||||||
uint backlog = 100;
|
|
||||||
bool shouldQuit = false;
|
|
||||||
const int BUFFSIZE = 4096;
|
|
||||||
|
|
||||||
TcpServerSocket? server = tcp::listen(
|
|
||||||
host, port, backlog,
|
|
||||||
SocketOption.REUSEADDR,
|
|
||||||
ip_protocol: IpProtocol.IPV4);
|
|
||||||
|
|
||||||
if (catch err = server) {
|
|
||||||
io::printfn("unable to create server socket %s", err);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
defer {
|
|
||||||
if (catch err = server.close()) {
|
|
||||||
io::printfn("error closing socket %s", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!shouldQuit) {
|
|
||||||
TcpSocket? client = tcp::accept(&server);
|
|
||||||
if (catch err = client) {
|
|
||||||
io::printfn("error accepting client %s", err);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
defer {
|
|
||||||
if (catch err = client.close()) {
|
|
||||||
io::printfn("error closing client socket %s", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char[BUFFSIZE] buffer;
|
|
||||||
|
|
||||||
List{String} data;
|
|
||||||
data.init(mem);
|
|
||||||
while (try usz read = client.read(&buffer)) {
|
|
||||||
//io::printfn("buffer %s", (String)buffer[:read]);
|
|
||||||
data.push((String)buffer[:read]);
|
|
||||||
if (read < BUFFSIZE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (item : data) {
|
|
||||||
io::printfn("%s", item);
|
|
||||||
if (item.contains("quit")) {
|
|
||||||
shouldQuit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user