int main() { tcpsock ls = tcplisten("*:5555"); assert(ls); go(client()); tcpsock as = tcpaccept(ls); tcpsend(as, "ABC", 3); int rc = tcpflush(as); assert(rc == 0); char buf[16]; ssize_t sz = tcprecvuntil(as, buf, sizeof(buf), '\n'); assert(sz == 4); assert(buf[0] == '1' && buf[1] == '2' && buf[2] == '3' && buf[3] == '\n'); sz = tcprecvuntil(as, buf, sizeof(buf), '\n'); assert(sz == 3); assert(buf[0] == '4' && buf[1] == '5' && buf[2] == '\n'); sz = tcprecvuntil(as, buf, 3, '\n'); assert(sz == 0); assert(buf[0] == '6' && buf[1] == '7' && buf[2] == '8'); tcpclose(as); tcpclose(ls); return 0; }
int main(int argc, char *argv[]) { int port = 5555; if(argc > 1) port = atoi(argv[1]); tcpsock ls = tcplisten(iplocal(NULL, port, 0)); if(!ls) { perror("Can't open listening socket"); return 1; } while(1) { tcpsock as = tcpaccept(ls, -1); tcpsend(as, "What's your name?\r\n", 19, -1); tcpflush(as, -1); char inbuf[256]; size_t sz = tcprecvuntil(as, inbuf, sizeof(inbuf), "\r", 1, -1); inbuf[sz - 1] = 0; char outbuf[256]; int rc = snprintf(outbuf, sizeof(outbuf), "Hello, %s!\n", inbuf); sz = tcpsend(as, outbuf, rc, -1); tcpflush(as, -1); tcpclose(as); } }
coroutine void dialogue(tcpsock as) { int64_t deadline = now() + 10000; tcpsend(as, "What's your name?\r\n", 19, deadline); if(errno != 0) goto cleanup; tcpflush(as, deadline); if(errno != 0) goto cleanup; char inbuf[256]; size_t sz = tcprecvuntil(as, inbuf, sizeof(inbuf), "\r", 1, deadline); if(errno != 0) goto cleanup; inbuf[sz - 1] = 0; char outbuf[256]; int rc = snprintf(outbuf, sizeof(outbuf), "Hello, %s!\r\n", inbuf); sz = tcpsend(as, outbuf, rc, deadline); if(errno != 0) goto cleanup; tcpflush(as, deadline); if(errno != 0) goto cleanup; cleanup: tcpclose(as); }
coroutine void dialogue(tcpsock as, chan ch) { chs(ch, int, CONN_ESTABLISHED); int64_t deadline = now() + 10000; tcpsend(as, "What's your name?\r\n", 19, deadline); if(errno != 0) goto cleanup; tcpflush(as, deadline); if(errno != 0) goto cleanup; char inbuf[256]; size_t sz = tcprecvuntil(as, inbuf, sizeof(inbuf), "\r", 1, deadline); if(errno != 0) goto cleanup; inbuf[sz - 1] = 0; char outbuf[256]; int rc = snprintf(outbuf, sizeof(outbuf), "Hello, %s!\r\n", inbuf); sz = tcpsend(as, outbuf, rc, deadline); if(errno != 0) goto cleanup; tcpflush(as, deadline); cleanup: if(errno == 0) chs(ch, int, CONN_SUCCEEDED); else chs(ch, int, CONN_FAILED); tcpclose(as); }
int main() { char buf[16]; tcpsock ls = tcplisten(iplocal(NULL, 5555, 0), 10); assert(ls); int fd = tcpdetach(ls); assert(fd != -1); ls = tcpattach(fd, 1); assert(ls); assert(tcpport(ls) == 5555); go(client(5555)); tcpsock as = tcpaccept(ls, -1); /* Test deadline. */ int64_t deadline = now() + 30; size_t sz = tcprecv(as, buf, sizeof(buf), deadline); assert(sz == 0 && errno == ETIMEDOUT); int64_t diff = now() - deadline; assert(diff > -20 && diff < 20); sz = tcpsend(as, "ABC", 3, -1); assert(sz == 3 && errno == 0); tcpflush(as, -1); assert(errno == 0); sz = tcprecvuntil(as, buf, sizeof(buf), "\n", 1, -1); assert(sz == 4); assert(buf[0] == '1' && buf[1] == '2' && buf[2] == '3' && buf[3] == '\n'); sz = tcprecvuntil(as, buf, sizeof(buf), "\n", 1, -1); assert(sz == 3); assert(buf[0] == '4' && buf[1] == '5' && buf[2] == '\n'); sz = tcprecvuntil(as, buf, 3, "\n", 1, -1); assert(sz == 3); assert(buf[0] == '6' && buf[1] == '7' && buf[2] == '8'); tcpclose(as); tcpclose(ls); return 0; }
void client(ipaddr addr, int messages, chan results) { int sent = 0; tcpsock s = tcpconnect(addr, -1); if (s == NULL) { perror("tcpconnect"); goto out; } while (messages--) { tcpsend(s, "hello\n", 6, -1); if (errno != 0) { perror("tcpsend"); goto out; } tcpflush(s, -1); if (errno != 0) { perror("tcpflush"); goto out; } char buf[100]; size_t sz = tcprecvuntil(s, buf, sizeof(buf), "\n", 1, -1); if (errno != 0) { perror("tcprecvuntil"); goto out; } buf[sz - 1] = 0; if (sz != 6) { fprintf(stderr, "unexpedted return: %s\n", buf); goto out; } sent++; } out: tcpclose(s); chs(results, int, sent); }
void handler(tcpsock accepted_socket, chan channel) { // request name from connected client tcpsend(accepted_socket, "What's your name?\r\n", 19, -1); tcpflush(accepted_socket, -1); // send a message to the communication channel, signifying this connection chs(channel, int, 1); // capture the name, and create a response message char inbuf[256], outbuf[256]; size_t size = tcprecvuntil(accepted_socket, inbuf, sizeof(inbuf), "\r", 1, -1); inbuf[size-1] = 0; int rc = snprintf(outbuf, sizeof(outbuf), "Hello, %s!\r\n", inbuf); // flush the message to the server tcpsend(accepted_socket, outbuf, rc, -1); cleanup: tcpflush(accepted_socket, -1); tcpclose(accepted_socket); }
/* Gets one CRLF-delimited line from the socket. Trims all leading and trailing whitesepace. Replaces any remaining whitespace sequences by single space. */ static int wsock_getline(wsock s, char *buf, size_t len, int64_t deadline) { size_t sz = tcprecvuntil(s->u, buf, len, "\r", 1, deadline); if(errno != 0) return -1; sz--; char c; tcprecv(s->u, &c, 1, deadline); if(errno != 0) return -1; if(c != '\n') { errno = EPROTO; return -1; } size_t i; for(i = 0; i != sz; ++i) { if(buf[i] < 32 || buf[i] > 127) { errno = EPROTO; return -1; } } i = 0; while(i != sz && isspace(buf[i])) ++i; size_t pos = 0; while(i != sz) { if(isspace(buf[i])) { while(i != sz && isspace(buf[i])) ++i; --i; } buf[pos++] = buf[i++]; } if(pos && isspace(buf[pos - 1])) --pos; return pos; }