{"id":20348005,"url":"https://github.com/shlomnissan/echo-server","last_synced_at":"2026-05-29T21:31:20.600Z","repository":{"id":65551844,"uuid":"594244867","full_name":"shlomnissan/echo-server","owner":"shlomnissan","description":"📢 A simple TCP echo server with different methods for sync multiplexing","archived":false,"fork":false,"pushed_at":"2023-02-01T15:58:27.000Z","size":34,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-14T23:05:36.841Z","etag":null,"topics":["bsd-sockets","multiplexing","tcp","tcp-server"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shlomnissan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-28T00:04:33.000Z","updated_at":"2023-01-30T18:24:02.000Z","dependencies_parsed_at":"2023-02-15T19:30:40.817Z","dependency_job_id":null,"html_url":"https://github.com/shlomnissan/echo-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shlomnissan%2Fecho-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shlomnissan%2Fecho-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shlomnissan%2Fecho-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shlomnissan%2Fecho-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shlomnissan","download_url":"https://codeload.github.com/shlomnissan/echo-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241877505,"owners_count":20035417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bsd-sockets","multiplexing","tcp","tcp-server"],"created_at":"2024-11-14T22:18:54.133Z","updated_at":"2026-05-29T21:31:20.558Z","avatar_url":"https://github.com/shlomnissan.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📢 echo-server\n\nThis project is a simple implementation of a TCP echo server using BSD sockets that I put together to explore different methods of synchronous I/O multiplexing in a Linux environment. It allows for the selection of a multiplexing method using an application argument. Available methods are select, poll, and epoll, and each method has performance and cross-platform compatibility trade-offs.\n\n*Note*: this program uses epoll, a Linux kernel system call, so it can only be compiled in a Linux environment.\n\n## Usage\n```\necho_server 8080 epoll\n```\n- `arg[1]` the port you want the server to bind to.\n- `arg[2]` the multiplexing method you want to use (select, poll, or epoll).\n\nBoth arguments are required.\n\nThe simplest way to test the server is using `telnet`.\n\n## Synchronous I/O multiplexing methods\n\n| Method  | Summary |\n| ------------- | ------------- |\n| [select()](https://man7.org/linux/man-pages/man2/select.2.html) | \u003cul\u003e\u003cli\u003eThe primary advantage is portability. BSD sockets and WINSOCK interfaces fully support it.\u003c/li\u003e \u003cli\u003eIt can only monitor up to 1024 file descriptors. Unix man recommends that modern applications use `poll()` or `epoll()`.\u003c/li\u003e \u003cli\u003eIt isn't very efficient. The kernel has to iterate through the max file descriptor value, even when a single file descriptor is watched.\u003c/li\u003e \u003cli\u003eFile descriptor sets are reconstructed on return, so each subsequent call must reinitialize them.\u003c/li\u003e\u003c/ul\u003e  |\n| [poll()](https://man7.org/linux/man-pages/man2/poll.2.html) | \u003cul\u003e\u003cli\u003eIt improves on the `select()` method, but it's only available in UNIX.\u003c/li\u003e\u003cli\u003eIt stores file descriptors in an array, so it doesn't need to iterate through the max file descriptor value.\u003c/li\u003e\u003cli\u003eThe `poll()` system call separates input and output events, allowing the array to be reused without having to reinitialize it.\u003c/li\u003e\u003cli\u003eThe time complexity of `poll()`, like `select()` is O(n), and it's still a slow solution when a large number of file descriptors is used.\u003c/li\u003e\u003c/ul\u003e |\n| [epoll()](https://man7.org/linux/man-pages/man7/epoll.7.html) | \u003cul\u003e\u003cli\u003eIt performs better than `select()` and `poll()`, but it's only available on Linux and not standardized by POSIX.\u003c/li\u003e\u003cli\u003eThe time complexity of `epoll()` is O(1).\u003c/li\u003e\u003cli\u003e`epoll_wait()` only returns file descriptors ready for IO operations, so there's no need to iterate through the entire set.\u003c/li\u003e\u003cli\u003eIt allows adding and removing file descriptors while waiting.\u003c/li\u003e\u003cli\u003eIt can be used either as an edge-triggered or a level-triggered interface.\u003c/li\u003e\u003c/ul\u003e |\n\n## Licence\n```\n    ____       __                             __  \n   / __ )___  / /_____ _____ ___  ____ ______/ /__\n  / __  / _ \\/ __/ __ `/ __ `__ \\/ __ `/ ___/ //_/\n / /_/ /  __/ /_/ /_/ / / / / / / /_/ / /  / ,\u003c   \n/_____/\\___/\\__/\\__,_/_/ /_/ /_/\\__,_/_/  /_/|_|  \n                                                  \nCopyright (c) 2023 Shlomi Nissan\nhttps://betamark.com\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshlomnissan%2Fecho-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshlomnissan%2Fecho-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshlomnissan%2Fecho-server/lists"}