From d950ec2981bce060356d98c22f9093f4e425b45c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 9 Jun 2017 21:09:19 +0300 Subject: [PATCH] samples: net: Add socket-based echo server example The example source code is POSIX-compatible (modulo include files), i.e. can be built and behaves the same way for Zephyr and a POSIX system (e.g. Linux). Makefile.posix is available for the latter. Signed-off-by: Paul Sokolovsky --- samples/net/socket_echo/Makefile | 18 ++++++ samples/net/socket_echo/Makefile.posix | 4 ++ samples/net/socket_echo/prj_qemu_x86.conf | 26 ++++++++ samples/net/socket_echo/src/Makefile | 3 + samples/net/socket_echo/src/socket_echo.c | 76 +++++++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 samples/net/socket_echo/Makefile create mode 100644 samples/net/socket_echo/Makefile.posix create mode 100644 samples/net/socket_echo/prj_qemu_x86.conf create mode 100644 samples/net/socket_echo/src/Makefile create mode 100644 samples/net/socket_echo/src/socket_echo.c diff --git a/samples/net/socket_echo/Makefile b/samples/net/socket_echo/Makefile new file mode 100644 index 00000000000..7f9b4a97a88 --- /dev/null +++ b/samples/net/socket_echo/Makefile @@ -0,0 +1,18 @@ +# Makefile - simple socket-based echo server + +# +# Copyright (c) 2017 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +# + +BOARD ?= qemu_x86 +CONF_FILE ?= prj_$(BOARD).conf + +include $(ZEPHYR_BASE)/Makefile.inc + +ifeq ($(CONFIG_NET_L2_BLUETOOTH), y) + QEMU_EXTRA_FLAGS = -serial unix:/tmp/bt-server-bredr +else + include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack +endif diff --git a/samples/net/socket_echo/Makefile.posix b/samples/net/socket_echo/Makefile.posix new file mode 100644 index 00000000000..7bf5def40dd --- /dev/null +++ b/samples/net/socket_echo/Makefile.posix @@ -0,0 +1,4 @@ +# This makefile builds socket_echo sample for POSIX system, like Linux + +socket_echo: src/socket_echo.c + $(CC) $^ -o $@ diff --git a/samples/net/socket_echo/prj_qemu_x86.conf b/samples/net/socket_echo/prj_qemu_x86.conf new file mode 100644 index 00000000000..2435a9e4058 --- /dev/null +++ b/samples/net/socket_echo/prj_qemu_x86.conf @@ -0,0 +1,26 @@ +# General config +CONFIG_NEWLIB_LIBC=y + +# Networking config +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=n +CONFIG_NET_TCP=y +CONFIG_NET_SOCKETS=y +CONFIG_NET_SOCKETS_POSIX_NAMES=y + +# Network driver config +CONFIG_NET_SLIP_TAP=y +CONFIG_TEST_RANDOM_GENERATOR=y + +# Without CONFIG_NET_BUF_LOG printf() doesn't work +CONFIG_NET_BUF_LOG=y + +# Network address config +CONFIG_NET_APP_SETTINGS=y +CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_APP_PEER_IPV4_ADDR="192.0.2.2" + +# Network debug config +#CONFIG_NET_DEBUG_SOCKETS=y +CONFIG_SYS_LOG_NET_LEVEL=2 diff --git a/samples/net/socket_echo/src/Makefile b/samples/net/socket_echo/src/Makefile new file mode 100644 index 00000000000..073377e184f --- /dev/null +++ b/samples/net/socket_echo/src/Makefile @@ -0,0 +1,3 @@ +include $(ZEPHYR_BASE)/samples/net/common/Makefile.common + +obj-y += socket_echo.o diff --git a/samples/net/socket_echo/src/socket_echo.c b/samples/net/socket_echo/src/socket_echo.c new file mode 100644 index 00000000000..c9fa4c8b572 --- /dev/null +++ b/samples/net/socket_echo/src/socket_echo.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#ifndef __ZEPHYR__ + +#include +#include +#include +#include + +#define init_net() + +#else + +#include +#include +#include + +void init_net(void) +{ + int ret = net_sample_app_init("socket_echo", NET_SAMPLE_NEED_IPV4, + K_SECONDS(3)); + + if (ret < 0) { + printf("Application init failed\n"); + k_panic(); + } +} + +#endif + +int main(void) +{ + int serv; + struct sockaddr_in bind_addr; + + init_net(); + + serv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + bind_addr.sin_family = AF_INET; + bind_addr.sin_addr.s_addr = htonl(INADDR_ANY); + bind_addr.sin_port = htons(4242); + bind(serv, (struct sockaddr *)&bind_addr, sizeof(bind_addr)); + + listen(serv, 5); + + while (1) { + struct sockaddr_in client_addr; + socklen_t client_addr_len = sizeof(client_addr); + char addr_str[32]; + int client = accept(serv, (struct sockaddr *)&client_addr, + &client_addr_len); + inet_ntop(client_addr.sin_family, &client_addr.sin_addr, + addr_str, sizeof(addr_str)); + printf("Connection from %s\n", addr_str); + + while (1) { + char buf[128]; + int len = recv(client, buf, sizeof(buf), 0); + + if (len == 0) { + break; + } + send(client, buf, len, 0); + } + + close(client); + printf("Connection from %s closed\n", addr_str); + } +}