先把服务端与客户端的连接代码敲出来

服务端
IPAddress ip = new IPAddress(new byte[] { 127, 1, 1, 1 });
TcpListener server = new TcpListener(ip, 8005);
server.Start();//服务端启动侦听
TcpClient client = server.AcceptTcpClient();//接受发起连接对象的同步方法
Console.WriteLine("收到客户端连接请求")//如果没有客户端请求连接,这句话是无法Print out的
客户端
IPAddress ip=IPAddress.Parse("127.1.1.1");
TcpClient client=new TcpClient();
client.Connect(ip,8005);//8005端口号,必须与服务端给定的端口号一致,否则天堂无门

先看看服务端的特殊标记的那句代码

AcceptTcpClient() 这个方法是一个同步方法,在没有接受到连接请求的时候,位于它下面的代码是不会被执行的,也就是线程阻塞在这里,进行不下去了,想出城没有城防长官的批复是不能的,嘿嘿...

连接后,客户端要发送数据给服务端,先贴代码再说

NetworkStream dataStream=client.GetStream();
string msg="服务端亲启!";
byte[] buffer=Encoding.default.getBytes(msg);
stream.write(buffer,0,buffer.length);
//这段代码呈接上面那段客户端代码

NetworkStream 在网络中进行传输的数据流,也就是说传输数据必须写入此流中,才能够互通有无。
首先客户端先获取用于发送信息的流,然后将要发送的信息存入byte[] 数组中(数据必须是byte[] 才能够写入流中),最后就是写入传输的数据流,发送

聪明的你想必已经知道如何在服务端获取数据了
既然客户端费力的把数据包装发给服务端了,那么服务端自然要把包装拆了,得到数据,上代码:

NetworkStream dataStream=client.GetStream();
byte[] buffer=new byte[8192];
int dataSize=dataStream.Read(buffer,0,8192);
Console.write(Encoding.default.GetString(buffer,0,dataSize));
//这段代码呈接上面那段服务端代码

代码一写,我觉得再说多余了,不过还要在说一两句,嘿嘿
Read() 方法需要三个参数,1,存储数据的缓存空间。2,写入数据的起始点就是从存储空间的什么位置开始写入数据。3,就是存储空间的大小。返回写入数据的大小值
Encoding.default.GetString() 参数解析
1,存储数据的缓存空间。2,从什么位置开始接收数据。3,接收多少数据

以上只是再简单不过的数据发送,而且只是客户端发给服务端,只能发一条信息而已,那如果想彼此互发,并且想发多少条信息都可以,怎么办呢

首先基于以上的代码,编写一个winform的小程序

界面很简单,要实现的功能就是客户端与服务端互发信息。

感觉还是直接上代码吧

服务端的全部代码如下:

using hepu.BloodModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;namespace hepu
{public partial class Blood5_TCP : Form{public Blood5_TCP(){InitializeComponent();}public delegate void showData(string msg);//委托,防止跨线程的访问控件,引起的安全异常private const int bufferSize = 8000;//缓存空间private TcpClient client;private TcpListener server;/// <summary>/// 结构体:Ip、端口/// </summary>struct IpAndPort{public string Ip;public string Port;}private void Blood5_TCP_Load(object sender, EventArgs e){}private void button1_Click(object sender, EventArgs e){if (txtIP.Text.Trim() == string.Empty){return;}if (txtPort.Text.Trim() == string.Empty){return;}Thread thread = new Thread(reciveAndListener);//如果线程绑定的方法带有参数的话,那么这个参数的类型必须是object类型,所以讲ip,和端口号 写成一个结构体进行传递IpAndPort ipHePort = new IpAndPort();ipHePort.Ip = txtIP.Text;//服务器IPipHePort.Port = txtPort.Text;//为程序设置端口thread.Start((object)ipHePort);}/// <summary>/// 侦听客户端的连接并接收客户端发送的信息/// </summary>/// <param name="ipAndPort">服务端Ip、侦听端口</param>private void reciveAndListener(object ipAndPort){IpAndPort ipHePort = (IpAndPort)ipAndPort;IPAddress ip = IPAddress.Parse(ipHePort.Ip);server = new TcpListener(ip, int.Parse(ipHePort.Port));server.Start();//启动监听rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "服务端开启侦听....\n");//  btnStart.IsEnabled = false;//获取连接的客户端对象client = server.AcceptTcpClient();rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "有客户端请求连接,连接已建立!");//AcceptTcpClient 是同步方法,会阻塞进程,得到连接对象后才会执行这一步  //获得流NetworkStream reciveStream = client.GetStream();#region 循环监听客户端发来的信息do{byte[] buffer = new byte[bufferSize];int msgSize;try{lock (reciveStream){msgSize = reciveStream.Read(buffer, 0, bufferSize);}if (msgSize == 0)return;string msg = Encoding.Default.GetString(buffer, 0, bufferSize);TextBox1.text=msg;//接收到的信息放到textBox里//rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "\n客户端曰:" + result + "\r\n");}catch (Exception ex){server.Stop();string aa = ex.Message;MessageBox.Show(aa);rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "\n 出现异常:连接被迫关闭");break;}} while (true);#endregion}/// <summary>/// 将数据包转换成xml格式   提取有效参数/// </summary>/// <param name="hl7data"></param>/// <returns></returns>public NewBlood5  FormatXml(string hl7data){XmlDocument xmlObject = HL7ToXmlConverter.ConvertToXmlObject(hl7data);NewBlood5 blood5 = new NewBlood5();//实体类//根据node去获取需要的数据blood5.Brcode = HL7ToXmlConverter.GetText(xmlObject, "MSH/MSH.54", 0);blood5.WBC = HL7ToXmlConverter.GetText(xmlObject, "MSH/MSH.662", 0);return blood5;}}
}

客户端代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;namespace Blood
{public partial class TCP : Form{public TCP(){InitializeComponent();}TcpClient client;private const int bufferSize = 8000;NetworkStream sendStream;public delegate void showData(string msg);private void TCP_Load(object sender, EventArgs e){}private void button1_Click(object sender, EventArgs e){if (txtIP.Text.Trim() == string.Empty){return;}if (txtPort.Text.Trim() == string.Empty){return;}IPAddress ip = IPAddress.Parse(txtIP.Text);client = new TcpClient();client.Connect(ip, int.Parse(txtPort.Text));rtbtxtShowData.AppendText("开始连接服务端....\n");rtbtxtShowData.AppendText("已经连接服务端\n");//获取用于发送数据的传输流sendStream = client.GetStream();Thread thread = new Thread(ListenerServer);thread.Start();}private void button2_Click(object sender, EventArgs e){if (client != null){//要发送的信息if (txtSendMsg.Text.Trim() == string.Empty)return;string msg = txtSendMsg.Text.Trim();//将信息存入缓存中byte[] buffer = Encoding.Default.GetBytes(msg);//lock (sendStream)//{sendStream.Write(buffer, 0, buffer.Length);//}rtbtxtShowData.AppendText("发送给服务端的数据:" + msg + "\n");txtSendMsg.Text = string.Empty;}}private void ListenerServer(){do{try{int readSize;byte[] buffer = new byte[bufferSize];lock (sendStream){readSize = sendStream.Read(buffer, 0, bufferSize);}if (readSize == 0)return;rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "服务端曰:" + Encoding.Default.GetString(buffer, 0, readSize) + "\n");}catch{rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "报错");}//将缓存中的数据写入传输流} while (true);}}
}

其中用到了,多线程处理还有委托,因为以上我们用到的不管是Connect,还是AcceptTcpClient方法 都是同步方法,会阻塞进程,导致窗口无法自由移动

 rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "服务端开启侦听....\n");

Ok,至此客户端与服务端的数据传递就大功告成了,这只是一个很简单的操作,如果有多个客户端呢?要求异步通信,怎么办?不急,慢慢来,不积跬步无以至千里

如果有什么错的,希望指正。

C#网络编程之---TCP协议的同步通信(相互发送接收数据)相关推荐

  1. 网络编程——基于TCP协议的通讯录【课程设计】

    网络编程--基于TCP协议的通讯录[课程设计] 本文目录 网络编程--基于TCP协议的通讯录[课程设计] 一.设计题目和要求 设计目标: 课程设计系统组成及模块功能: 二.设计内容 服务端 客户端 S ...

  2. 基于ZYNQ-7000的AI加速器设计之PS端(ARM)网络编程(TCP协议)

    前注:ARM端的TCP协议编程步骤和UDP协议编程步骤完全相同,只是在ARM端的C代码实现不同,在本次TCP协议实现过程中我们主要利用了官方提供的Demo,然后根据自己的需要加以改写,具体过程如下. ...

  3. Linux 系统应用编程——网络编程(TCP 协议三次握手过程)

    TCP(Transmission Control Protocol) 传输控制协议  TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种 ...

  4. linux串口编程实例_Linux 网络编程——原始套接字实例:发送 UDP 数据包

    以太网报文格式: IP 报文格式: UDP 报文格式: 校验和函数: /*******************************************************功能:校验和函数参 ...

  5. step5 . day6 网络编程 基于TCP协议的多并发模式(使用多进程、多线程、select函数分别实现)...

    实现TCP服务器端多路并发的方法有①多进程②多线程③IO多路复用(select poll epoll函数) 1.多进程实现并发模式(仅在服务器端更改之前代码实现) 服务器端 #include < ...

  6. Java学习笔记53(网络编程:TCP协议案例)

    简易的案例 客户端: package demo;import java.io.IOException; import java.io.InputStream; import java.io.Outpu ...

  7. 网络编程及TCP/UDP协议

    网络编程 1.1.概述 地球村:你在西安,一个在美国 打电话--连接--接了--通话 TCP 发短信--发完了就完事了--接收 UDP(丢包) 计算机网络: 计算机网络系统就是利用通信设备和线路将地理 ...

  8. 网络编程及三大协议(TCP + UDP + Http)

    网络编程及三大协议(TCP + UDP + Http) 一.网络编程 1.计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络 ...

  9. C语言网络编程:TCP客户端实现

    文章目录 客户端通信步骤 为什么客户端没有bind和listen 客户端connect函数介绍 局域网内客户端和服务器通信代码实例 客户端通信步骤 根据基本TCP网络通信编程模型 我们可以知道客户端的 ...

  10. day30,网络编程和各种协议

    网络编程    1.网络通讯协议 理论知识点 学习网络编程的目的? 什么是互联网 网: 由多个节点相互连接组成 渔网 蜘蛛网 计算互联网: 由多台计算机通过某种介质相互连接而组成 互联网之所以存在就是 ...

最新文章

  1. seg是伪操作符,用来取后面符号的段地址
  2. docker安装运行rancher脚本
  3. SAP Spartacus shipping address页面请求2.1 - setDefaultAddress
  4. Dijkstra算法——计算一个点到其他所有点的最短路径的算法
  5. 4 微信公众号开发 被动回复消息 回复没有反应怎么办
  6. C++ 堆区内存分配
  7. LeetCode(1002)——查找常用字符(JavaScript)
  8. 【Vue】—计算属性
  9. 一文教你如何用 Python 将 iPhone “玩弄于股掌之中”!
  10. python工资一般多少p-预测python数据分析师的工资
  11. 19-random猜数
  12. 不再支持Postman集合v1格式,无法直接导入
  13. Legion:基于Haskell开发的极简区块链服务器
  14. 传说中WM手机工程测试命令
  15. 【苹果家庭群发推】创作AppleScript脚本来控制MacOS附有的iMessage客户端停止考据,近似于组iMessage
  16. AS运行安装失败,真机提示“软件包似乎无效”问题
  17. Cesium面积测量之思路解析加源码
  18. Summary - 文件导出测试
  19. 如何设置修改网页中滚动条
  20. error CS1061

热门文章

  1. linux内存寻址解析 (二)
  2. K - 最少拦截系统(动态规划)
  3. 1.5.2 Prime Palindromes 回文质数(构造回文)
  4. python学习(一)----基础语法
  5. linux--用户和组管理
  6. animals中文谐音_张杰pretty white lies中文音译歌词
  7. python 爬取实时数据django显示_python脚本采集服务器数据通过API提交到django web服务器,然后展示在页面上...
  8. linux硬盘只读脚本 zabbix,Zabbix如何设置脚本告警
  9. spring java 定时任务_spring定时任务的几种实现方式
  10. centos7 如何安装部署k8s_如何在CentOS 7上正确安装Chromium