一个简单的TCP服务器
1.只接收一个连接然后自动关闭的服务端代码
1 -module(socket_server). 2 3 -export([start_nano_server/0]). 4 5 start_nano_server() -> 6 % 监听来自端口2345上的连接,消息打包规则{packet, 4} -> 每个应用程序都是从一个4字节长的头部开始 7 % gen_tcp:listen -> {ok, ListenSocket} | {error, Reason}, ListenSocket为监听套接字 8 {ok, ListenSocket} = gen_tcp:listen(2345, [binary, {packet, 4}, 9 {reuseaddr, true}, 10 {active, true}]), 11 % gen_tcp:accept(Listensocket)调用时,程序会暂停并等待一个连接 12 % 当一个新的连接建立起来时会返回变量Socket,该变量绑定到新建连接的套接字上 13 % 通过Socket套接字,服务器就可以和发起连接的客户机进行通信 14 {ok, Socket} = gen_tcp:accept(ListenSocket), 15 % 关闭监听套接字,此后服务器不会继续处于监听状态,也无法建立新的连接,但并不影响已经建立的连接套接字 16 % 只是阻止新连接的建立 17 gen_tcp:close(ListenSocket), 18 loop(Socket). 19 20 loop(Socket) -> 21 receive 22 {tcp, Socket, Bin} -> 23 io:format("Server received binary = ~p~n", [Bin]), 24 Str = binary_to_term(Bin), % 对接收数据解码(反整编) 25 io:format("Server(unpacked) ~p~n", [Str]), 26 Reply = lib_misc:string2value(Str), % 对回应数据进行编码(整编) 27 io:format("Server replying = ~p~n", [Reply]), 28 % send(Socket, Packet) -> ok | {error, Reason}, Packet -> iodata() 29 gen_tcp:send(Socket, term_to_binary(Reply)), 30 loop(Socket); 31 {tcp_closed, Socket} -> 32 io:format("Server socket closed~n") 33 end.
2.顺序型服务器
1 %% 顺序型服务器 2 -module(socket_server_order). 3 4 -export([start_nano_server/0]). 5 6 start_nano_server() -> 7 % 监听来自端口2345上的连接,消息打包规则{packet, 4} -> 每个应用程序都是从一个4字节长的头部开始 8 % gen_tcp:listen -> {ok, ListenSocket} | {error, Reason}, Listen为监听套接字 9 {ok, ListenSocket} = gen_tcp:listen(2345, [binary, {packet, 4}, 10 {reuseaddr, true}, 11 {active, true}]), 12 req_loop(ListenSocket). 13 14 req_loop(ListenSocket) -> 15 {ok, Socket} = gen_tcp:accept(ListenSocket), 16 loop(Socket), 17 req_loop(ListenSocket). 18 19 loop(Socket) -> 20 receive 21 {tcp, Socket, Bin} -> 22 io:format("Server received binary = ~p~n", [Bin]), 23 Str = binary_to_term(Bin), 24 io:format("Server(unpacked) ~p~n", [Str]), 25 Reply = lib_misc:string2value(Str), 26 io:format("Server replying = ~p~n", [Reply]), 27 gen_tcp:send(Socket, term_to_binary(Reply)), 28 loop(Socket); 29 {tcp_closed, Socket} -> 30 io:format("Server socket closed~n") 31 end.
3.并发型服务器
1 %% 并发型服务器 2 -module(socket_server_order). 3 4 -export([start_nano_server/0]). 5 6 start_nano_server() -> 7 % 监听来自端口2345上的连接,消息打包规则{packet, 4} -> 每个应用程序都是从一个4字节长的头部开始 8 % gen_tcp:listen -> {ok, ListenSocket} | {error, Reason}, Listen为监听套接字 9 {ok, ListenSocket} = gen_tcp:listen(2345, [binary, {packet, 4}, 10 {reuseaddr, true}, 11 {active, true}]), 12 spawn(fun() -> par_connect(ListenSocket) end). 13 14 par_connect(ListenSocket) -> 15 {ok, Socket} = gen_tcp:accept(ListenSocket), 16 spawn(fun() -> par_connect(ListenSocket) end), 17 loop(Socket). 18 19 loop(Socket) -> 20 receive 21 {tcp, Socket, Bin} -> 22 io:format("Server received binary = ~p~n", [Bin]), 23 Str = binary_to_term(Bin), 24 io:format("Server(unpacked) ~p~n", [Str]), 25 Reply = lib_misc:string2value(Str), 26 io:format("Server replying = ~p~n", [Reply]), 27 gen_tcp:send(Socket, term_to_binary(Reply)), 28 loop(Socket); 29 {tcp_closed, Socket} -> 30 io:format("Server socket closed~n") 31 end.
4.客户端代码
1 -module(socket_client). 2 3 -export([nano_client_eval/1]). 4 5 nano_client_eval(Str) -> 6 {ok, Socket} = gen_tcp:connect("localhost", 2345, 7 [binary, {packet, 4}]), 8 ok = gen_tcp:send(Socket, term_to_binary(Str)), 9 receive 10 {tcp, Socket, Bin} -> 11 io:format("Client received binary = ~p~n", [Bin]), 12 Val = binary_to_term(Bin), 13 io:format("Client result = ~p~n", [Val]), 14 gen_tcp:close(Socket) 15 end.
5.lib_misc模块
1 -module(lib_misc). 2 3 -export([string2value/1]). 4 5 string2value(L) -> string2value(L, []). 6 string2value([], N) -> list_to_tuple(lists:reverse(N)); 7 string2value([H|T], N) -> string2value(T, [H|N]).
6.测试
6.1只接收一个连接然后自动关闭的服务端代码测试
6.2顺序型服务器测试
6.3并发型测试
ps:顺序型服务器相对并发型服务器的区别在于:顺序型服务器忙于服务一个现存的连接时,如果又有新的客户机尝试连接服务器,那么这个连接就会在服务器排队,直到服务器完成对现有的服务为止,如果等待队列中的连接数目超过了监听套接字的能力,那么这个连接就会被拒绝,而并发型服务器则不会有该问题
转载于:https://www.cnblogs.com/huangxiaoyi/p/5709588.html
一个简单的TCP服务器相关推荐
- 笨办法学C 练习45:一个简单的TCP/IP客户端
练习45:一个简单的TCP/IP客户端 原文:Exercise 45: A Simple TCP/IP Client 译者:飞龙 我打算使用RingBuffer来创建一个非常简单的小型网络测试工具,叫 ...
- [C# 网络编程系列]专题十二:实现一个简单的FTP服务器
引言: 休息一个国庆节后好久没有更新文章了,主要是刚开始休息完心态还没有调整过来的, 现在差不多进入状态了, 所以继续和大家分享下网络编程的知识,在本专题中将和大家分享如何自己实现一个简单的FTP服务 ...
- 3-4:一个简单的HTTP服务器
文章目录 HTTP服务器 HTTP服务器 我们使用浏览器请求某一个网页时,浏览器会向相应的服务器发送请求,服务器得到请求后会将报文传送回来,然后浏览器解析,就形成了我们所看见到的网页 这里我们可以写一 ...
- 用python写一个简单的web服务器
人生苦短,我用python 简洁高效,这才是理想的语言啊 分享一点python的学习经验-----如何用python写一个简单的web服务器 首先,我们需要简单地了解一下网络通信协议,这里用白话介绍一 ...
- 通过python 构建一个简单的聊天服务器
构建一个 Python 聊天服务器 一个简单的聊天服务器 现在您已经了解了 Python 中基本的网络 API:接下来可以在一个简单的应用程序中应用这些知识了.在本节中,将构建一个简单的聊天服务器.使 ...
- libev实现简单的tcp服务器
本文将介绍如何用libev创建一个简单的tcp echo server服务器,实现一个简单的异步(asynchronous)tcp server的功能,该server接收客户端连接,然后读取已连接客户 ...
- 一个简单的RTMP服务器实现 --- RTMP实现要点
#PS:要转载请注明出处,本人版权所有 #PS:这个只是 < 我自己 >理解,如果和你的 #原则相冲突,请谅解,勿喷 背景 参考前置文章:<一个简单的RTMP服务器实现 - RTMP ...
- Mina、Netty、Twisted一起学(一):实现简单的TCP服务器
MINA.Netty.Twisted为什么放在一起学习?首先,不妨先分别看一下它们官方网站对其的介绍: MINA: Apache MINA is a network application frame ...
- 专题十二:实现一个简单的FTP服务器
引言: 在本专题中将和大家分享如何自己实现一个简单的FTP服务器.在我们平时的上网过程中,一般都是使用FTP的客户端来对商家提供的服务器进行访问(上传.下载文件),例如我们经常用到微软的SkyDriv ...
最新文章
- 【maven】初识maven
- Ambari在离线环境中安装Hadoop集群
- CSS媒体查询 @media
- solaris下常见文件压缩/解压方式简单小结—待续中
- 从零入门 FreeRTOS操作系统之信号量
- 反骨仔的 2016 年度全文目录索引
- 视觉注意力机制(上)
- android之微信分享图片
- mysql置信度支持度,关于支持度和置信度的说明
- 每日编程-20170326
- 基于嵌入式系统的gnash最小库依赖关系
- Intent在Activity间的传值
- 从cocos2d-x到unity看游戏研发、设计中一些要点
- 电脑重装系统苹果电脑开不了机的原因分析
- 手把手系列--STM32H750移植FreeRTOS(二)--优化编译速度
- 自旋锁(spin lock)学习
- 【GIS小案例】点聚合效果的实现
- spinnaker-简介
- Java编程思想——复用类
- cad打开卡死_cad2010打开就卡死怎么回事_教你解决cad2010打开就卡死问题