[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. golang整数与小数间的加减乘除

    我们假设你需要 整数与小数一起进行运算,或者 整数除以整数 得到小数这种运算 如果你使用了decimal, 那么之后所有的运算你都必须使用decimal, 因为通过它计算出来的结果的类型统统为deci ...

  2. Django—Form组件

    Django From简介 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比 ...

  3. 2.6. 案例:使用BeautifuSoup4的爬虫

    案例:使用BeautifuSoup4的爬虫 我们以腾讯社招页面来做演示:http://hr.tencent.com/position.php?&start=10#a 使用BeautifuSou ...

  4. YOLO---Darknet下的学习笔记

    YOLO.V3-Darknet下的学习笔记 @wp20180927 [目录] 一. 安装Darknet(仅CPU下) 2 1.1在CPU下安装Darknet方式 2 1.2在GPU下安装Darknet ...

  5. 7.caffe:create_lmdb.sh(数据预处理转换成lmdb格式)

    个人实践代码如下: #!/usr/bin/env sh # Create the imagenet lmdb inputs # N.B. set the path to the imagenet tr ...

  6. IPV4和IPV6的划分

    IP(Internet Protocol,网络互联协议)地址就是连接互联网的主机被分配或指派的一段数字标识,是传输报文组装时最重要的组成部分,用来在互联网中数据传输时标识源和目标主机. IPv4 IP ...

  7. Java工程师面试题集锦

    即将踏上找工作的征途,参考网上面试题库准备一波面试题,希望能找到理想中的工作,愿一切顺利. 一.Java基础 1.String类为什么是final的. 2.HashMap的源码,实现原理,底层结构. ...

  8. mysql主从同步监控---邮件告警

    #!/bin/bash #check MySQL_Slave Status #crontab time : MYSQLPORT=`netstat -na|grep "|awk -F[:&qu ...

  9. MyBatis-07-分页

    7.分页 思考:为什么要分页? 减少数据的处理量 7.1.使用Limit分页 select * from user limit startIndex,pageSize 使用Mybatis实现分页,核心 ...

  10. hdu3715 Go Deeper[二分+2-SAT]/poj2723 Get Luffy Out[二分+2-SAT]

    这题转化一下题意就是给一堆形如$a_i + a_j \ne c\quad (a_i\in [0,1],c\in [0,2])$的限制,问从开头开始最多到哪条限制全是有解的. 那么,首先有可二分性,所以 ...