Socket类型_nixio创建一个socket对象

写在前

在这里插入图片描述
在这里插入图片描述
今天看到
在这里插入图片描述
在这里插入图片描述
看到这样一个接口描述,不太清楚他的type,于是查阅了一番。

1、数据流套接字(Stream Socket)

数据流式是一种面向连接的Socket,针对于面向连接的TCP服务应用,使用使用比较高质量的TCP协议。它有以下一些特点:

(1) TCP提供可靠的连接。当TCP向另外一端发送数据时,它要求对方返回一个确认回答。如果没有收到确认,则会等待一段时间后重新发送,在数次重发失败后,TCP才会放弃发送。

(2) TCP为发送的数据进行排序。比如发送2048个字节,TCP可能将它分成大小为1024的两个段,并分别进行编号“1”和“2”。接收段将根据编号对数据进行重新排序并判断是否为重复数据。

(3) TCP提供流量控制。它会通知对方自己能够接受数据的容量,称为窗口,这样就确保不会发生缓冲区溢出的情况。

(4) TCP的连接是双工的。在给定连接上的应用进程在任何时刻既可以发送也可以接受数据。

在TCP中相当重要的一个概念就是建立一个TCP连接,也就是三次握手过程,理解它对于今后编程有非常大的帮助。下面我们就详细学习一下这个过程。

(1) 服务器必须准备好接收外来的连接。由调用socket、bind和listen函数完成,称为被动打开(passive open)。

(2) 客户通过调用connect进行主动打开(active open)。客户TCP发送一个SYN(同步)包,以告知服务器客户在这次连接中要发送数据的初始序列号。SYN数据包不包含数据,只有一个IP头、一个TCP头及其选项。

(3) 服务器确认客户的SYN,同时自己也发送一个SYN数据包,告知客户它自己在这次连接中发送数据的初始序列号。服务器分别对客户SYN的应答ACK,以及自己的SYN数据。

(4)客户返回对服务器SYN的确认应答ACK。

许多广泛应用的程序都使用数据流套接字,比如telnet、WWW浏览器使用的HTTP协议等。

2、数据报套接字(Datagram Socket)

数据报式Socket是一种无连接的套接字,对应于无连接的UDP服务应用,相应协议是UDP。

UDP提供无连接的服务,就是说UDP客户与服务器不必保持长期的连接关系。例如,一个UDP客户可以创建一个套接字并发送一个数据报给一个服务器,然后可以立即用同一个套接字发送另一个数据报给另一个服务器。UDP所面临的问题就是缺乏可靠性。因为它没有例如确认、超时重传等复杂机制,因此它不能保证数据的到达以及到达的次序。

那么我们在传送过程中,如果数据丢失了该怎么办呢?其实每个程序在UDP上都有自己的协议,如果在一定时间内没有收到对方发回的确认应答,它将重新发送,直到得到ACK。

UDP实现过程比较简单,因此在一定程度上效率较高,对于一些数据量小,无须交互的通信情况还是适用的。使用UDP的应用程序有:tftp、bootp等。

3、原始套接字(Raw Socket)

除了上面两种常用的套接字类型外,还有一类原始套接字(raw socket),在某些网络应用中担任重要角色。比如我们平时想看一看网络是否通达,就用ping命令测试一下。Ping命令用的是ICMP协议,因此我们不能通过建立一个SOCK_STREAM或SOCK_DGRAM来发送这个包,而只能自己亲自来构建ICMP包来发送。另外一种情况是,许多操作系统只实现了几种常用的协议,而没有实现其它如OSPE、GGP等协议。如果自己有必要编写位于其上的应用,就必须借助raw socket来实现,这是因为操作系统遇到自己不能够处理的数据包,就将这个包交给raw socket处理。

Raw socket的作用主要在三个方面:

(1) 通过raw socket来接收和发送ICMP协议包。

(2) 接收发向本机的但TCP/IP栈不能够处理的IP包。

(3) 用来发送一些自己指定源地址特殊作用的IP包。

根据nixio编写的工具类communication.lua

core={}

local h=require "luci.http"
local n=require "nixio"

core.ip="192.168.80.192"
core.port=8888
core.uri="/users"
core.method="GET"
core.charset="UTF-8"
core.rcvTimeout=20

--http data format
function core.httpData(data)
	core.uri="/users"
	return core.method.." "..core.uri.." HTTP/1.1\r\n"..
		"Host: "..core.ip..":"..core.port.."\r\n"..
		"Content-type: text/html;charset="..core.charset.."\r\n"..
		"Accept-Language: zh-cn\r\n"..
		"User-Agent: Mozilla/4.0(Compatible win32; MSIE)\r\n"..
		"Content-Length: "..string.len(data).."\r\n"..	
		"Connection: close\r\n\r\n"..
		data
end

--tcp protocol for http
function core.send(data)
	local position
	local t={}
	local tmp
	--stream is tcp
	local socket=nixio.socket("inet","stream")

	if not socket then
		return false, "创建socket失败"
	end

	if not socket:connect(core.ip,core.port) then
		socket:close()
		return false, "服务无响应,连接服务器"..core.ip..":"..core.port.."失败"
	end

	socket:setopt("socket","rcvtimeo",core.rcvTimeout)

	socket:send(core.httpData(data))

	repeat
		tmp=socket:recv(100)
	
		if tmp==false then
			socket:close()
			return false,"响应超时"
		end
		tmp=tostring(tmp)
		t[#t + 1] = tmp
	until #tmp < 1

	socket:close()
	
	local result=table.concat(t)
--[[	
	position=string.find(result,"\r\n\r\n")

	if position==nil then
		return false,"返回的数据格式不合法。数据:"..result
	end

	result=string.sub(result,string.find(result,"\r\n\r\n")+4)
--	result=string.sub(result,string.find(result,"{"),string.len(result)-string.find(result,"{")-1)
--]]	
	return result
end

--udp client
function core.udpc(host,port,data)

	local socket=nixio.socket("inet","dgram")
	if not socket then
		return false, "create socket failed!"
	end
	
	local num = socket:sendto(data,host,port)
	if num < 0 then
		socket:close()
		return false, "sendto "..host..":"..port.."failed!"
	end
	
	local t={}
	local tmp,cip,cport
--	repeat
		tmp,cip,cport = socket:recvfrom(8192)
		if tmp==false then
			socket:close()
			return false,"response timeout!"
		end
		tmp=tostring(tmp)
		t[#t + 1] = tmp
--	until #tmp < 1
	socket:close()
	return table.concat(t),cip,cport,num
	
end

--udp server
function core.udps(host,port,data)

	local socket=nixio.socket("inet","dgram")
	if not socket then
		return false, "create socket failed!"
	end
	
	socket:setopt("socket","rcvtimeo",20)

	local isBand = socket:bind(host,port)
	if not isBand then
		socket:close()
		return false, "band "..host..":"..port.."failed!"
	end

	local t={}
	local tmp,cip,cport
--	repeat
		tmp,cip,cport = socket:recvfrom(8192)
		if tmp==false then
			socket:close()
			return false,"response timeout!"
		end
		tmp=tostring(tmp)
		t[#t + 1] = tmp
--	until #tmp < 1
	local num = socket:sendto(data,cip,cport)
	socket:close()
	return table.concat(t),cip,cport,num
	
end

--tcp client
function core.tcpc(host,port,data)
	
	local socket=nixio.socket("inet","stream")
	if not socket then
		return false, "create socket failed!"
	end
	
	local isConn = socket:connect(host,port)
	if not isConn then
		socket:close()
		return false, "connect "..host..":"..port.."failed!"
	end
	
	socket:setopt("socket","rcvtimeo",20)
	local num = socket:write(data)
	
	local t={}
	local tmp
	repeat
		tmp=socket:recv(100)
		if tmp==false then
			socket:close()
			return false,"response timeout!"
		end
		tmp=tostring(tmp)
		t[#t + 1] = tmp
	until #tmp < 1
	socket:close()
	return table.concat(t),host,port,num		
	
end

--tcp server
function core.tcps(host,port,data)

	local socket=nixio.socket("inet","stream")
	if not socket then
		return false, "create socket failed!"
	end
	
	local isBand = socket:bind(host,port)
	if not isBand then
		socket:close()
		return false, "band "..host..":"..port.."failed!"
	end
	
	local isListen = socket:listen(50)
	if not isListen then
		socket:close()
		return false, "listen for connections failed!"
	end
	
--while true do	
	local client,cip,cport = socket:accept()
	local t={}
	local tmp
	repeat
		tmp=client:read(100)
		
		if tmp==false then
			client:close()
			return false,"response timeout!"
		end
		tmp=tostring(tmp)
		t[#t + 1] = tmp
	until #tmp < 1
	--it send ok,but client not receive for it's ip port not 192.168.80.192 then 192.168.56.1
	local num = client:write(data)
	print("write ok "..tostring(num))
--	socket:sendto(data,cip,cport)
	client:close()
	--it is most important for the close of sending msg!
	socket:close()
	return table.concat(t),cip,cport,num	
--end
end

return core

验证communication.lua使用test-nixio.htm根据java编写udp和tcp程序交互访问:

<%+header%>

<%
--[[
	local h=require "luci.http"
	local c=require "luci.communication"
	
	--test send method ok
--	h.write(c.send("luci web's page Client!"))
	--test tcpc method ok
	local res,ip,port,num=c.tcpc("192.168.80.192",8888,"Tcp client send ok!")
	h.write(res.."<br>")
	h.write(tostring(ip).."<br>")
	h.write(tostring(port).."<br>")
	h.write(tostring(num).."<br>")
--]]

--
	local h = require "luci.http"
	local c = require "luci.communication"
	--test tcps method rev ok,send erro,server need close in while.
	local res,ip,port,num =c.tcps("192.168.56.12",8081,"Tcp Server recevie success!\r\n\r\n")
	h.write(res.."</Br>")	
	h.write(ip.."</Br>")
	h.write(port.."</Br>")
	h.write(num.."<br>")
--
--[[
	local h = require "luci.http"
	local c = require "luci.communication"
	--test udp client send is ok,but receive error,solve by remove repeat.
	local res,ip,port,num =c.udpc("192.168.80.192",8088,"Udp Client send success!")
	h.write(res.."</Br>")	
	h.write(ip.."</Br>")
	h.write(port.."</Br>")
	h.write(num.."<br>")
--]]
--[[
	local h = require "luci.http"
	local c = require "luci.communication"
	--test udps ok,udp's receive do not permit repeat...until
	local res,ip,port,num =c.udps("192.168.56.12",8081,"Udp Server recevie success!")
	h.write(res.."</Br>")	
	h.write(ip.."</Br>")
	h.write(port.."</Br>")
	h.write(num.."<br>")
--]]
%>
<%+footer%>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值