go实现的简易TCP的客户端和服务器

时间:2022-09-25 14:39:12

今天介绍golang版本的通信基础:基于TCP的客户端和服务器实现,参考书籍:The Way To Go

那时学习java的时候也是做过通信的,当时是socket编程,服务器监听某一个端口,然后客户机去连接,简单的聊天室就实现了。后来有变成多线程的聊天室,可以进行群聊什么的了,后期可以传图片传音乐,加上UI那一块儿,山寨QQ就OK了。现在我来用golang实现一下简易的聊天室,实现了客户机连接服务器,给服务器发消息,服务器接受消息,客户机退出,服务器可以收到退出信息,以及多个客户机同时连入一个服务器。主要的思路和java一样的,服务器监听某一个端口,客户机去连接,然后发送消息就OK了。上代码了。
package main

//服务器端
import (
    "fmt"
    "log"
    "net" //支持通讯的包
)

//开始服务器
func startServer() {
    //连接主机、端口,采用tcp方式通信,监听7777端口
    listener, err := net.Listen("tcp", "localhost:7777")
    checkError(err)
    fmt.Println("建立成功!")
    for {
        //等待客户端接入
        conn, err := listener.Accept()
        checkError(err)
        //开一个goroutines处理客户端消息,这是golang的特色,实现并发就只go一下就好
        go doServerStuff(conn)
    }
}

//处理客户端消息
func doServerStuff(conn net.Conn) {
    nameInfo := make([]byte, 512) //生成一个缓存数组
    _, err := conn.Read(nameInfo)
    checkError(err)

for {
        buf := make([]byte, 512)
        _, err := conn.Read(buf) //读取客户机发的消息
        flag := checkError(err)
        if flag == 0 {
            break
        }
        fmt.Println(string(buf)) //打印出来
    }
}

//检查错误
func checkError(err error) int {
    if err != nil {
        if err.Error() == "EOF" {
            //fmt.Println("用户退出了")
            return 0
        }
        log.Fatal("an error!", err.Error())
        return -1
    }
    return 1
}
func main() {
    //开启服务
    startServer()
}

以上是服务器的实现,具体看代码注释
package main

//客户机
import (
    "bufio"
    "fmt"
    "log"
    "net"
    "os"
    "strings"
)

//连接服务器
func connectServer() {
    //接通
    conn, err := net.Dial("tcp", "localhost:7777")
    checkError(err)
    fmt.Println("连接成功!\n")
    //输入
    inputReader := bufio.NewReader(os.Stdin)
    fmt.Println("你是谁?")
    name, _ := inputReader.ReadString('\n')
    //
    trimName := strings.Trim(name, "\r\n")
    conn.Write([]byte(trimName + " 接入了\n "))
    for {
        fmt.Println("我们来聊天吧!按quit退出")
        //读一行
        input, _ := inputReader.ReadString('\n')
        trimInput := strings.Trim(input, "\r\n")
        //如果quit就退出
        if trimInput == "quit" {
            fmt.Println("再见")
            conn.Write([]byte(trimName + " 退出了 "))
            return
        }
        //写出来
        _, err = conn.Write([]byte(trimName + " says " + trimInput))
    }
}

//检查错误
func checkError(err error) {
    if err != nil {
        log.Fatal("an error!", err.Error())
    }
}

 

//主函数
func main() {
    //连接servser
    connectServer()
}

以上是客户机代码,具体看注释

运行的时候,分别go run server和client,你变可以看到这样就可以连接成功了。
 服务器只用开一个,客户机可以开任意个,并且相互之间没有干扰。

OK,一个简单的多线程聊天室就实现了。后期可以加上更多的功能,但无非就是去处理输入输出,重点都已经有了。

go实现的简易TCP的客户端和服务器的更多相关文章

  1. tcp程序设计--客户端获取服务器输入输出流

    tcp程序设计--客户端获取服务器输入输出流 思路: 第一步:实例化一个ServerSocket对象(服务器套接字),用来等待网络上的请求(也就是等待来连接的套接字) 第二步:调用accept()方法 ...

  2. 2015/12/14 Python网络编程,TCP/IP客户端和服务器初探

    一直不是很清楚服务器的定义,对于什么是服务器/客户端架构也只有一个模糊的感觉.最近开始学习,才明白一些什么服务器和客户端的关系. 所谓的服务器,就是提供服务的东西,它是一个硬件或者软件,可以向一个或者 ...

  3. tcp/ip客户端与服务器

    单击“发送数据”把数据发送到指定IP地址的指定端口号 using System; using System.Collections.Generic; using System.ComponentMod ...

  4. 清晰易懂TCP通信原理解析(附demo、简易TCP通信库源码、解决沾包问题等)C#版

    目录 说明 TCP与UDP通信的特点 TCP中的沾包现象 自定义应用层协议 TCPLibrary通信库介绍 Demo演示 未完成功能 源码下载 说明 我前面博客中有多篇文章讲到了.NET中的网络编程, ...

  5. Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)

    转载地址:http://blog.csdn.net/mad1989/article/details/9147661 ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当 ...

  6. Java基础知识强化之网络编程笔记10:TCP之客户端读取文本文件服务器控制台输出

    1. TCP之客户端读取文本文件服务器控制台输出 (1)客户端:(发送数据到服务端) package cn.itcast_10; import java.io.BufferedReader; impo ...

  7. Java基础知识强化之网络编程笔记09:TCP之客户端键盘录入服务器写到文本文件中

    1. TCP之客户端键盘录入服务器写到文本文件中 (1)客户端: package cn.itcast_09; import java.io.BufferedReader; import java.io ...

  8. TCP的客户端搭建

    一.设计目标 之前已经写过了TCP服务器原理及通过visual studio 验证 SOCKET编程:搭建一个TCP服务器,这里我们搭建一个TCP客户端界面并对各功能进行实现.设计效果如下: 二.实验 ...

  9. c语言的tcp和udp客户端和服务器

    都是最简单的用来记忆. this is my 的git地址:https://github.com/yanjinyun/cLanguageTcpUdp tcp最简单的服务器: int main(int ...

随机推荐

  1. 附录B 安装MySql数据库

    B.1  卸载旧的MaySql程序 第一步   查找以前是否安装有mysql 使用命令查看是否已经安装过mysql: #rpm -qa | grep -i mysql 如果没有结果,则可以进行mysq ...

  2. Struts框架——(三)动态ActionForm

    一.DynaActionForm的引入意义 使用ActionForm把表单数据单独封装起来,而且提供了自动的数据验证,简化了代码的编写,给我们带来了极大的方便. 但是,ActionForm也存在一些明 ...

  3. js 禁止表单提交的方法(文件上传)

    添加图片上传的表单,在form 添加属性onsubmit,提交之前会执行其中的方法,若返回FALSE,不会提交,返回TRUE,才会提交 <form method="post" ...

  4. 一个php soap的错误记录

    今天使用php soap实现两个系统之间的互通 在写好php的soapserver后,client端调用一直报 looks like we got no XML document,尝试好久后无法解决 ...

  5. 【转】windows7的桌面右键菜单的&OpenCurlyDoubleQuote;新建”子菜单,在注册表哪个位置,如何在&OpenCurlyDoubleQuote;新建&quot&semi;里面添加一个新项

    点击桌面,就会弹出菜单,然后在“新建”中就又弹出可以新建的子菜单栏.office与txt 的新建都是在这里面的.我想做的事情是:在右键菜单的“新建” 中添加一个“TQ文本”的新建项,然后点击它之后,桌 ...

  6. org&period;apache&period;commons&period;dbutils&period;QueryRunner 执行sqlserver的存储过程

    执行不带输出参数的存储过程与 执行普通update  sql没有什么区别,直接调用即可: 示例代码: public Boolean startResidentialInfoStatistics(Str ...

  7. C C&plus;&plus;实现创建目录

    下面代码是C.C++可以使用的创建目录的函数及头文件,这是引用的opencv,haartraining中的一种方式. #include <direct.h> //不同系统可能不一样,这是在 ...

  8. Fetching android sdk component information

    原文地址: Android Studio安装以及Fetching android sdk component information超时的解决方案 - sonyi - 博客园 http://www.c ...

  9. 【Java重构系列】重构31式之搬移方法

    重构第二式:搬移方法 (Refactoring 2: Move Method) 毋容置疑,搬移方法(Move Method)应该是最常用的重构手段之一,正因为太常用而且较为简单,以至于很多人并不认为它 ...

  10. 关于Platinum库的MediaRender具体C&plus;&plus;代码实现探讨

    接上篇博文 NDK下 将Platinum SDK 编译成so库 (android - upnp) 讲述了如何利用该代码库编译给android程序调用的so库,其中也提到了,在使用sample-upnp ...