golang(4):编写socket服务,简单支持命令

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/46881213 转载请必须注明出处!

1,socket服务

使用golang开发socket服务还是非常简单的。
socket的库都封装好了。
参考文档:
https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/08.1.md

2,简单例子

package main

import (
    "fmt"
    "net"
    "os"
    "time"
)

func main() {
    tcpAddr, err := net.ResolveTCPAddr("tcp4", ":8080")
    checkError(err)
    listener, err := net.ListenTCP("tcp", tcpAddr)
    checkError(err)
    for {//循环处理
        conn, err := listener.Accept()
        if err != nil {
            continue
        }
        go handleClient(conn)//创建一个goroutinue处理
    }
}

func handleClient(conn net.Conn) {
    defer conn.Close()
    daytime := time.Now().String()
    conn.Write([]byte(daytime)) // don't care about return value
    // we're finished with this client
}
func checkError(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

通过net.ListenTCP(“tcp”, tcpAddr) 创建一个服务,
然后用for循环,通过listener.Accept() 再创建一个goroutinue处理。

测试,使用telnet测试

$ telnet 127.0.0.1 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
2015-07-14 17:33:59.602610026 +0800 CSTConnection closed by foreign host.

3,增加交互处理

当客户端输入参数的时候,服务端可以处理。
这里遇到几个问题一个是客户端输入的带回车\r\n要替换掉。
在一个字符串比较用等号即可,但是byte转换字符串长度不一样,需要特殊处理。

package main

import (
    "net"
    "os"
    "fmt"
    "time"
    "strings"
)

func main() {
    //  println(os.Args[0])
    //  println("Hello world!")

    tcpAddr , err := net.ResolveTCPAddr("tcp4", ":8080")
    checkError(err, 1)

    listener , err := net.ListenTCP("tcp", tcpAddr)
    checkError(err, 2)

    for {
        conn, err := listener.Accept()
        if err != nil {
            continue
        }
        go handleClient(conn)
    }

    os.Exit(0)
}

func handleClient(conn net.Conn) {
    conn.SetReadDeadline(time.Now().Add(2 * time.Minute)) // 设置两分钟超时。
    user_cmd := make([]byte, 128) //设置用户输入的命令
    defer conn.Close()

    for {
        read_len, err := conn.Read(user_cmd)

        if err != nil {
            fmt.Println(err)
            break
        }
        if read_len == 0 {
            break // connection already closed by client
        }

        //fmt.Println(string(user_cmd))
        //fmt.Println(len(string(user_cmd)))//长度是128,而不是time字符串的长度。
        //####################需要特殊处理字符串,找到每一个字符,然后累加。####################
        cmd_str := ""
        for i := 0; i < len(user_cmd); i ++ {
            //println(cmd_str[i])
            if user_cmd[i] == 0 {
                break
            }else {
                cmd_str += string(user_cmd[i])
            }
        }

        //替换字符
        cmd_str = strings.Replace(cmd_str, "\r\n", "", -1)

        if cmd_str == "time" {
            time_now := time.Now().String()
            conn.Write([]byte(time_now))
        }else if cmd_str == "exit" {//退出命令。
            conn.Close()
        }

        user_cmd = make([]byte, 128) // clear last read content
    }
}

func checkError(err error, num int) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "%d) Fail Error:%s", num, err.Error())
        os.Exit(1)
    }
}

客户端telnet调用:当输入time返回时间,当输入exit关闭连接。

$ telnet 127.0.0.1 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
time
2015-07-14 17:44:06.743505631 +0800 CST
exit
Connection closed by foreign host.

4,总结

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/46881213 转载请必须注明出处!

使用golang开发服务端还是非常方便的。
代码非常简洁,配合上goroutinue就可以写出高效的服务端代码。

时间: 2015-07-14

golang(4):编写socket服务,简单支持命令的相关文章

Ruby中的Socket编程简单入门

  这篇文章主要介绍了Ruby中的Socket编程简单入门,是Ruby网络编程学习中的基础知识,需要的朋友可以参考下 Ruby提供了两个访问级别的网络服务.在一个较低的水平,可以访问底层的操作系统,它可以实现面向连接和无连接协议的客户端和服务器支持基本的socket. Ruby也具有程序库,提供更高级别的访问特定的应用程序级的网络协议,如FTP,HTTP等. 这篇教程介绍 Ruby Socket编程概念及讲解一个简单的实例. 什么是Sockets? 套接字是一个双向通信信道的端点.socket能

利用LoadRunner编写socket性能测试脚本

一.概述 Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力.其中就有此次要讨论的socket套接字操作. 二.socket概述 socket是操作系统中I/O系统的网络延伸部分,它扩展了操作系统的基本I/O到网络通信,使进程和机器之间的通信成为可能.如果想完全地理解socket在Loadrunner中如何工作的,熟悉一些关于它的历史会很有帮助. 当前常用的socket,最早起源于BSD UNIX类的操作系统.在UNIX系统上,比如BSD,把对网络的支持加入操作系统,以一

Ruby中的Socket编程简单入门_ruby专题

 Ruby提供了两个访问级别的网络服务.在一个较低的水平,可以访问底层的操作系统,它可以实现面向连接和无连接协议的客户端和服务器支持基本的socket. Ruby也具有程序库,提供更高级别的访问特定的应用程序级的网络协议,如FTP,HTTP等. 这篇教程介绍 Ruby Socket编程概念及讲解一个简单的实例. 什么是Sockets? 套接字是一个双向通信信道的端点.socket能在一个进程,进程在同一台机器之间,或在不同的机器上的进程之间的进行通信. 套接字可实施过许多不同类型的通道:Unix

如何在Ruby中编写微服务?

[编者按]本文作者为 Pierpaolo Frasa,文章通过详细的案例,介绍了在Ruby中编写微服务时所需注意的方方面面.系国内 ITOM 管理平台 OneAPM 编译呈现. 最近,大家都认为应当采用微服务架构.但是,又有多少相关教程呢?我们来看看这篇关于用Ruby编写微服务的文章吧. 人人都在讨论微服务,但我至今也没见过几篇有关用Ruby编写微服务的.像样的教程.这可能是因为许多Ruby开发人员仍然最喜欢Rails架构(这没什么不好,Rails本身也没什么不好,但是Ruby可以做到的事还有很

java Socket实现简单在线聊天(一)

最近的项目有一个在线网页交流的需求,由于很久以前做过的demo已经忘记的差不多了,因此便重新学习一下. 我计划的大致实现步骤分这样几大步: 1.使用awt组件和socket实现简单的单客户端向服务端持续发送消息: 2.结合线程,实现多客户端连接服务端发送消息: 3.实现服务端转发客户端消息至所有客户端,同时在客户端显示: 4.把awt组件生成的窗口界面改成前端jsp或者html展示的界面,java socket实现的客户端改为前端技术实现. 这里首先实现第一步的简单功能,难点在于: 1.没有用过

单独写的一个socket服务应该怎么部署?部署到哪个平台?

问题描述 RT:想问下:我通过java代码实现了一个socket服务端(可以启动socket服务,接收客户端请求,给客户端回复响应),在eclipse中调试启动服务,调测是OK的:但是这个服务怎么才能集成或部署到一个类似于jetty或tomcat容器中呢?(而不是每次通过eclipse启动),知道的能告诉我一个具体方法吗?感激! 解决方案 应该是c/s程序吧,直接在服务器上调用java命令运行main类就行,就像我们开始学习java时需要手动编译运行一样,先javac编译,再java运行你把在你

vc socket木马-用VC编写socket木马的问题

问题描述 用VC编写socket木马的问题 下面的是某一本书上我看到的代码 服务器端代码如下: // easyDoor.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #include #pragma comment (lib, "Winmm") #pragma comment (lib, "ws2_32&

php socket通信简单实现_php实例

socket通信的原理在这里就不说了,它的用途还是比较广泛的,我们可以使用socket来做一个API接口出来,也可以使用socket来实现两个程序之间的通信,我们来研究一下在php里面如何实现socket通信. 由于socket服务端的代码要监听端口,等待接收请求,所以php在做socket服务的时候需要将php文件运行在CMD里面. 如果要使php文件可以在CMD里面运行,则需要进行如下设置: 1.添加环境变量,名字为PHP_HOME,值为php文件安装目录下的.exe文件地址,如D:\wam

编写Socket客户端和服务器程序,客户端读取本地文件的数据,发送到服务器,服务器接收并存储到文件中。

问题描述 2.编写Socket客户端和服务器程序,客户端读取本地文件的数据,发送到服务器,服务器接收并存储到文件中.消息格式:字段长度(单位字节)内容--------------------------------------------------------------------len8整个消息长度,不包括这4个字节,类型为longfile_name_length1文件名长度,bytefile_namefile_name_length文件名,Stringdata_length8文件数据长度