[net]tcp和udp&socket

socket特性

  • 总是成对出现

  • 是全双工的(同时支持收发)(两个channel绑在一起)

应用程序
- cs模式(客户端开发)
- bs模式(web开发)

net包api基础

都是客户端主动发数据(client request)

一共有3个soket。用于通信的有2个。另一个用于监听ip端口

// 服务端

import (
"net"
) listener, err := net.Listen("tcp", "127.0.0.1:8000") //生成监听socket
defer listener.Close() conn, err := listener.Accept() //[**阻塞] 生成读写socket
defer conn.Close() buf := make([]byte, 4096)
n, err := conn.Read(buf) //[**阻塞]
//读客户端数据(client request)
conn.Write(buf[:n]) //写数据给客户端
//客户端

conn, err := net.Dial("tcp", "127.0.0.1:8000")
defer conn.Close() conn.Write([]byte("Are you Ready?")) //写数据 buf := make([]byte, 4096) //读数据
n, err := conn.Read(buf)
fmt.Println("服务器回发:", string(buf[:n]))

实现conn复用: 循环读写

//server

func main() {
listener, _ := net.Listen("tcp", ":3000")
defer listener.Close()
conn, _ := listener.Accept()
defer conn.Close()
buf := make([]byte, 1024)
for {
n, _ := conn.Read(buf)
if n==0{ //客户端关闭时候server退出
return
}
fmt.Println(string(buf[:n]))
conn.Write([]byte("i am server"))
time.Sleep(time.Second / 3)
}
}
// client

func main() {
conn, _ := net.Dial("tcp", ":3000")
defer conn.Close()
buf := make([]byte, 1024)
for {
conn.Write([]byte("hi server")) n, _ := conn.Read(buf)
fmt.Println(string(buf[:n]))
time.Sleep(time.Second/3)
}
}

server支持并发

// server

func main() {
listener, _ := net.Listen("tcp", ":3000")
defer listener.Close()
for {
conn, _ := listener.Accept()
go func(conn net.Conn) {
defer conn.Close()
buf := make([]byte, 1024)
for {
n, _ := conn.Read(buf) //已关闭的chan中往出读数据会一直读出零值
if n == 0 {
return
}
fmt.Println(string(buf[:n]))
conn.Write([]byte("i am server"))
time.Sleep(time.Second / 3)
}
}(conn)
} time.Sleep(time.Second * 1000)
}
//client

func main() {
conn, _ := net.Dial("tcp", ":3000")
defer conn.Close()
buf := make([]byte, 1024)
for {
conn.Write([]byte("hi server")) n, _ := conn.Read(buf)
fmt.Println(string(buf[:n]))
time.Sleep(time.Second/3)
}
}

server并发-处理退出等.问题

// 并发版的server: 复用lisntner.Accept

package main

import (
"net"
"fmt"
"strings"
) func HandlerConnect(conn net.Conn) { defer conn.Close() // 获取连接的客户端 Addr
addr := conn.RemoteAddr()
fmt.Println(addr, "客户端成功连接!") // 循环读取客户端发送数据
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
//fmt.Println(buf[:n])
if "exit\n" == string(buf[:n]) || "exit\r\n" == string(buf[:n]) {
fmt.Println("服务器接收的客户端退出请求,服务器关闭")
return
}
if n == 0 {
fmt.Println("服务器检测到客户端已关闭,断开连接!!!")
return
}
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("服务器读到数据:", string(buf[:n])) // 使用数据 // 小写转大写,回发给客户端
conn.Write([]byte(strings.ToUpper(string(buf[:n]))))
}
} func main() {
// 创建监听套接字
//listener, err := net.Listen("tcp", "127.0.0.1:8001")
listener, err := net.Listen("tcp", "192.168.15.78:8001")
if err != nil {
fmt.Println("net.Listen err:", err)
return
}
defer listener.Close() // 监听客户端连接请求
for {
fmt.Println("服务器等待客户端连接...")
conn, err := listener.Accept()
if err != nil {
fmt.Println("listener.Accept err:", err)
return
}
// 具体完成服务器和客户端的数据通信
go HandlerConnect(conn)
}
}
//并发版的客户端

package main

import (
"net"
"fmt"
"os"
) func main() {
// 主动发起连接请求
conn, err := net.Dial("tcp", "192.168.15.78:8001")
if err != nil {
fmt.Println("net.Dial err:", err)
return
}
defer conn.Close()
// 获取用户键盘输入( stdin ),将输入数据发送给服务器
go func() {
str := make([]byte, 4096)
for {
n, err := os.Stdin.Read(str)
if err != nil {
fmt.Println("os.Stdin.Read err:", err)
continue
}
//写给服务器, 读多少,写多少!
conn.Write(str[:n])
}
}() // 回显服务器回发的大写数据
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
if n == 0 {
fmt.Println("检查到服务器关闭,客户端也关闭")
return
}
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("客户端读到服务器回发:", string(buf[:n]))
}
}

[go]socket编程的更多相关文章

  1. Linux下的C Socket编程 -- server端的继续研究

    Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...

  2. java socket编程(li)

    一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以 ...

  3. Python Socket 编程——聊天室示例程序

    上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...

  4. Linux下的C Socket编程 -- server端的简单示例

    Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...

  5. Linux下的C Socket编程 -- 获取对方IP地址

    Linux下的C Socket编程(二) 获取域名对应的IP地址 经过上面的讨论,如果我们想要连接到远程的服务器,我们需要知道对方的IP地址,系统函数gethostbyname便能够实现这个目的.它能 ...

  6. Linux下的C Socket编程 -- 简介与client端的处理

    Linux下的C Socket编程(一) 介绍 Socket是进程间通信的方式之一,是进程间的通信.这里说的进程并不一定是在同一台机器上也有可能是通过网络连接的不同机器上.只要他们之间建立起了sock ...

  7. python网络编程-socket编程

     一.服务端和客户端 BS架构 (腾讯通软件:server+client) CS架构 (web网站) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二.OSI七层 ...

  8. Socket编程实践(2) Socket API 与 简单例程

    在本篇文章中,先介绍一下Socket编程的一些API,然后利用这些API实现一个客户端-服务器模型的一个简单通信例程.该例子中,服务器接收到客户端的信息后,将信息重新发送给客户端. socket()函 ...

  9. Socket编程实践(1) 基本概念

    1. 什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口.TCP/IP协议的底层部分已经被内核实现了,而应用层是用户需要实现的,这部分程序工作在用户空间.用户空间的程序需要通 ...

  10. [转]C语言SOCKET编程指南

    1.介绍 Socket编程让你沮丧吗?从man pages中很难得到有用的信息吗?你想跟上时代去编Internet相关的程序,但是为你在调用 connect() 前的bind() 的结构而不知所措?等 ...

随机推荐

  1. mysql 利用 case 批量更新

  2. OS 常见函数使用

    os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'. os.getcwd:得 ...

  3. JAVA中AES对称加密和解密以及与Python兼容

    引言:本文主要解决Java中用AES加密及解密,同时可通过Python脚本对Java加密后的字符进行解密的操作. 由于近期工作中用到需要使用Java对一串密钥进行加密,并且后台通过Python语言读取 ...

  4. <meta http-equiv="X-UA-Compatible" content="IE=edge">详解

    X-UA-Compatible是针对IE8新加的一个设置,对于IE8之外的浏览器是不识别的. 这个区别与content="IE=7"在无论页面是否包含<!DOCTYPE> ...

  5. Matlab---绘图及其位置摆放

    Matlab---绘图及其位置摆放 [@WP@20180509] 一.绘图函数 (1)绘制二维图形 (1.1) plot( ) 函数的应用格式. 1,plot(x). 当x 为一向量时,以x 元素的值 ...

  6. percona-toolkit主从同步整理(MySQL)

    前言:MYSQL主从同步架构是目前使用最多的数据库架构之一,尤其是负载比较大的网站,因此对于主从同步的管理也就显得非常重要.而数据作为软件的核心部分,对于其有效的管理显得更为重要.随着时间的推移,软件 ...

  7. 为什么说Redis是单线程的以及Redis为什么这么块

    一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级等问题,这些看似 ...

  8. 一段有关线搜索的从python到matlab的代码

    在Udacity上很多关于机器学习的课程几乎都是基于python语言的,博主“ttang”的博文“重新发现梯度下降法——backtracking line search”里对回溯线搜索的算法实现也是用 ...

  9. [MySQL优化] -- 如何使用SQL Profiler 性能分析器

    mysql 的 sql 性能分析器主要用途是显示 sql 执行的整个过程中各项资源的使用情况.分析器可以更好的展示出不良 SQL 的性能问题所在. 下面我们举例介绍一下 MySQL SQL Profi ...

  10. hivesql中的concat函数,concat_ws函数,concat_group函数之间的区别

    一.CONCAT()函数CONCAT()函数用于将多个字符串连接成一个字符串.使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为 +---- ...