一、通过socket我们模拟请求网易

package main;

import (
"net"
"log"
"io/ioutil"
"fmt"
) func chkError(err error) {
if err != nil {
log.Fatal(err);
}
} func main() {
//我们模拟请求网易的服务器
//ResolveTCPAddr用于获取一个TCPAddr
//net参数是"tcp4"、"tcp6"、"tcp"
//addr表示域名或IP地址加端口号
tcpaddr, err := net.ResolveTCPAddr("tcp4", "www.163.com:80");
chkError(err); //DialTCP建立一个TCP连接
//net参数是"tcp4"、"tcp6"、"tcp"
//laddr表示本机地址,一般设为nil
//raddr表示远程地址
tcpconn, err2 := net.DialTCP("tcp", nil, tcpaddr);
chkError(err2); //向tcpconn中写入数据
_, err3 := tcpconn.Write([]byte("GET / HTTP/1.1 \r\n\r\n"));
chkError(err3); //读取tcpconn中的所有数据
data, err4 := ioutil.ReadAll(tcpconn);
chkError(err4); //打印出数据
fmt.Println(string(data));
}

 

二、通过socket创建简单的服务端

package main;

import (
"net"
"log"
) func chkError(err error) {
if err != nil {
log.Fatal(err);
}
} func main() {
//创建一个TCP服务端
tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
chkError(err);
//监听端口
tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
chkError(err2);
//死循环的处理客户端请求
for {
//等待客户的连接
//注意这里是无法并发处理多个请求的
conn, err3 := tcplisten.Accept();
//如果有错误直接跳过
if err3 != nil {
continue;
} //向客户端发送数据,并关闭连接
conn.Write([]byte("hello,client \r\n"));
conn.Close();
}
}

通过xshell的telnet方法测试。

三、改进上面的代码,使用goroutine来处理用户的请求

package main;

import (
"log"
"net"
"time"
) func chkError(err error) {
if err != nil {
log.Fatal(err);
}
} //单独处理客户端的请求
func clientHandle(conn net.Conn) {
defer conn.Close(); conn.Write([]byte("hello " + time.Now().String()));
} func main() {
//创建一个TCP服务端
tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
chkError(err);
//监听端口
tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
chkError(err2);
//死循环的处理客户端请求
for {
//等待客户的连接
conn, err3 := tcplisten.Accept();
//如果有错误直接跳过
if err3 != nil {
continue;
} //通过goroutine来处理用户的请求
go clientHandle(conn);
}
}

四、连续的处理客户端发送的请求,根据cmd命令不同,返回不同数据。

package main;

import (
"net"
"time"
"log"
"strings"
) func chkError(err error) {
if err != nil {
log.Fatal(err);
}
} //单独处理客户端的请求
func clientHandle(conn net.Conn) {
//设置当客户端3分钟内无数据请求时,自动关闭conn
conn.SetReadDeadline(time.Now().Add(time.Minute * 3));
defer conn.Close(); //循环的处理客户的请求
for {
data := make([]byte, 256);
//从conn中读取数据
n, err := conn.Read(data);
//如果读取数据大小为0或出错则退出
if n == 0 || err != nil {
break;
}
//去掉两端空白字符
cmd := strings.TrimSpace(string(data[0:n]));
//发送给客户端的数据
rep := "";
if(cmd == "string") {
rep = "hello,client \r\n";
} else if (cmd == "time") {
rep = time.Now().Format("2006-01-02 15:04:05");
}
//发送数据
conn.Write([]byte(rep));
}
} func main() {
tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
chkError(err);
tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
chkError(err2);
for {
conn, err3 := tcplisten.Accept();
if err3 != nil {
continue;
}
go clientHandle(conn);
}
}

go语言中net包tcp socket的使用的更多相关文章

  1. go语言中sync包和channel机制

    文章转载至:https://www.bytelang.com/article/content/A4jMIFmobcA= golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"Go&quo ...

  2. golang语言中bytes包的常用函数,Reader和Buffer的使用

    bytes中常用函数的使用: package main; import ( "bytes" "fmt" "unicode" ) //byte ...

  3. golang语言中os包的学习与使用(文件,目录,进程的操作)

    os中一些常用函数的使用: package main; import ( "os" "fmt" "time" "strings&q ...

  4. C语言中,如何通过socket得到对端IP地址

    struct sockaddr_in clientaddr1; memset(&clientaddr1, 0x00, sizeof(clientaddr1)); socklen_t nl=si ...

  5. Go语言中Path包用法

    // path package main import ( "fmt" "os" "path" "path/filepath&qu ...

  6. go语言中strings包中的Trim函数的作用是什么

    答:Trim函数原型如下: func Trim(s string, cutset string) string 去掉字符串s中首部以及尾部与字符串cutset中每个相匹配的字符,如: s=" ...

  7. go语言中log包的使用

    package main import ( "github.com/robertkrimen/otto" "log" ) func main() { log.P ...

  8. go语言中strings包常用方法

    strings.HasPrefix(s string, prefix string) bool:判断字符串s是否以prefix开头 strings.HasSuffix(s string, suffix ...

  9. go语言中regexp包中的函数和方法

    // regexp.go ------------------------------------------------------------ // 判断在 b 中能否找到正则表达式 patter ...

随机推荐

  1. a stop job is running for Security Auditing Services

    内核是3.10.0-514.el7,启动时有如下报错: a stop job is running for Security Auditing Services(56s / 1min 30s) 系统启 ...

  2. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  3. unity3d热更新插件uLua学习整理

    前言 IOS不能热更新,不是因为不能用反射,是因为System.Reflection.Assembly.Load 无法使用System.Reflection.Emit 无法使用System.CodeD ...

  4. PowerDesigner 修改table背景色

    Tools->Display Preferences(显示参数选择)->Format->Table->Modify->Fill->Fill color 出处:htt ...

  5. anchor_generator.proto:11:3: Expected "required", "optio nal", or "repeated"

    转自:https://github.com/tensorflow/models/issues/1834 When I use the commond " protoc object_dete ...

  6. js高级-原型链

    JavaScript是基于原型的面向对象的语言(相当于一个基类,父类),而不是像Java通过类模板构造实例,通过原型实现属性函数的复用 函数都有 prototype属性 指向函数的原型对象 只有函数根 ...

  7. spring注解之@Lazy

    今天主要从以下几方面来介绍一下@Lazy注解 @Lazy注解是什么 @Lazy注解怎么使用 1,@Lazy注解是什么   @Lazy注解用于标识bean是否需要延迟加载,源码如下: @Target({ ...

  8. 1.3.6、CDH 搭建Hadoop在安装之前(端口---DistCp使用的端口)

    DistCp使用的端口 列出的所有端口都是TCP. 在下表中,每个端口的“ 访问要求”列通常是“内部”或“外部”.在此上下文中,“内部”表示端口仅用于组件之间的通信; “外部”表示该端口可用于内部或外 ...

  9. windows环境安装zabbix客户端

    安装windows版zabbix客户端 一.下载客户端 在数据盘新建一个zabbix_agent目录 浏览器打开 https://www.zabbix.com/download_agents 选择”z ...

  10. 游戏编程模式KeyNote

    [游戏编程模式KeyNote] 1.命令模式. 重做在游戏中并不常见,但重放常见.一种简单的重放实现是记录游戏每帧的状态,这样它可以回放,但那会消耗太多的内存.相反,很多游戏记录每个实体每帧运行的命令 ...