设为首页 收藏本站
查看: 706|回复: 0

[经验分享] 记录golang及nginx-lua的tcp通讯代码

[复制链接]

尚未签到

发表于 2016-12-28 08:06:33 | 显示全部楼层 |阅读模式
  golang代码如下(src/simple/main.go)

package main
import (
"log"
"net"
"strconv"
"strings"
"sync"
"time"
)
const (
msg_length = 10240
)
type Control struct {
conn  net.TCPConn
mutex sync.Mutex
}
//store request map
var requestMap map[string]*Control
func proxy(conn *net.TCPConn) {
defer conn.Close()
var data = make([]byte, 1024)
for {
_, err := conn.Read(data)
if err != nil {
log.Println("proxy disconnect from " + conn.RemoteAddr().String())
return
}
var commands = strings.Split(string(data), " ")
if len(commands) <= 1 || commands[1] == "" {
log.Println("proxy receive bad commands : " + string(data))
return
}
var id = commands[0]
var n, tn int
if rclient, ok := requestMap[id]; ok {
log.Println("client " + commands[0] + " do command " + commands[1])
_, err = rclient.conn.Write([]byte(commands[1] + "\r\n"))
if err != nil {
rclient.conn.Close()
delete(requestMap, id)
break
}
var msglen = 0
var msg []string
var tdata = make([]byte, 2048)
var rdata []byte
tn = 0
for {
rclient.mutex.Lock()
rclient.conn.SetReadDeadline(time.Now().Add(1 * time.Millisecond))
n, err = rclient.conn.Read(tdata)
rclient.mutex.Unlock()
if err != nil {
if strings.HasSuffix(err.Error(), "timeout") == false {
rclient.conn.Close()
delete(requestMap, id)
break
}
}
if n > 0 {
if tn == 0 && n > 0 {
msg = strings.Split(string(tdata[:n]), "_")
msglen, err = strconv.Atoi(msg[0])
if err != nil {
break
}
rdata = append(rdata, tdata[len(msg[0])+1:n]...)
} else {
rdata = append(rdata, tdata[0:n]...)
}
tn = tn + n
if tn >= msglen+len(msg[0])+1 {
break
}
}
}
conn.Write(rdata[:msglen])
} else {
log.Println("client is offline " + id)
conn.Write([]byte("offline"))
}
break
}
}
//
func TcpMain(ip string, port int, router bool) {
//start tcp server
listen, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP(ip), port, ""})
if err != nil {
log.Fatalln("listen port error")
return
}
log.Println("start tcp server " + ip + " " + strconv.Itoa(port))
defer listen.Close()
//listen new request
var id string
for {
conn, err := listen.AcceptTCP()
if err != nil {
log.Println("receive connection failed")
continue
}
if router == true {
var tdata = make([]byte, 256)
conn.SetReadDeadline(time.Now().Add(3 * time.Second))
var n, err = conn.Read(tdata)
if err != nil {
conn.Close()
continue
}
id = string(tdata[0:n])
if rcontrol, ok := requestMap[id]; ok {
rcontrol.mutex.Lock()
rcontrol.conn.Close()
rcontrol.mutex.Unlock()
delete(requestMap, id)
}
log.Println("connected from " + id + " addr " + conn.RemoteAddr().String())
var control = &Control{}
control.conn = *conn
requestMap[id] = control
} else {
go proxy(conn)
}
}
}
func main() {
requestMap = make(map[string]*Control)
go TcpMain("127.0.0.1", 1988, false)
TcpMain("0.0.0.0", 1987, true)
}
  nginx-lua配置如下(其中lua-resty-http使用这个版本)

lua_package_path "/usr/local/openresty/nginx/conf/lua-resty-http-master/lib/?.lua;;";
init_worker_by_lua_file /usr/local/openresty/nginx/conf/connect.lua;
lua_socket_keepalive_timeout 600;
  conf/connect.lua代码如下

local function proxy()
local shutdown = 0
while true do
if ngx.worker.exiting() then
break
end
local tcpsocket = ngx.socket.tcp()
local ok, err = tcpsocket:connect("127.0.0.1", 1987)
if not ok then
ngx.timer.at(5,proxy)
break
else
tcpsocket:send("0")
while true do
if ngx.worker.exiting() then
shutdown = 1
break
end
local result = ""
tcpsocket:settimeout(600000)
local line, err, partial = tcpsocket:receive()
if not line then
tcpsocket:close()
break
else
line = string.gsub(line, "^%s*(.-)%s*$", "%1")
local http = require("resty.http")
local httpc = http.new()
local res, err = httpc:request_uri("http://www.ciaos.com"..line, {
method = "POST",
body = "username=root",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
if not res then
tcpsocket.send("0_err")
else                                          
local len = string.len(res.body)
tcpsocket:send(len .. "_" .. res.body)
end  
end         
end                                 
if shutdown == 1 then
break  
end                     
end                                         
end                                                                  
end                                             
local ok, err = ngx.timer.at(0,proxy)        
if not ok then                        
ngx.log(ngx.ERR, "timer error")                                               
end
  php测试代码

public function console()
{
$command= $this->input->get("cmd");
if(is_null($command) or $command == false){
echo "cmd not found";
return;
}
$port = 1988;
$ip = "127.0.0.1";
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
return;
}
$result = socket_connect($socket, $ip, $port);
if ($result < 0) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
return;
}
$in = "0 $command end";
if(!socket_write($socket, $in, strlen($in))) {
echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n";
}else {
}
$out = socket_read($socket, 8192);
echo $out;
socket_close($socket);
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-320357-1-1.html 上篇帖子: nginx + tomcat 负载均衡实现客户端缓存 下篇帖子: 用 logstash 统计 Nginx 的 http_accounting 模块输出
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表