参考:http://www.cnblogs.com/jzxx/p/5630516.html

一、原作者的这段话很好,先引用一下:

Socket的Send方法,并非大家想象中的从一个端口发送消息到另一个端口,它仅仅是拷贝数据到基础系统的发送缓冲区,然后由基础系统将发送缓冲区的数据到连接的另一端口。值得一说的是,这里的拷贝数据与异步发送消息的拷贝是不一样的,同步发送的拷贝,是直接拷贝数据到基础系统缓冲区,拷贝完成后返回,在拷贝的过程中,执行线程会IO等待, 此种拷贝与Socket自带的Buffer空间无关,但异步发送消息的拷贝,是将Socket自带的Buffer空间内的所有数据,拷贝到基础系统发送缓冲区,并立即返回,执行线程无需IO等待,所以异步发送在发送前必须执行SetBuffer方法,拷贝完成后,会触发你自定义回调函数ProcessSend,在ProcessSend方法中,调用SetBuffer方法,重新初始化Buffer空间。

二、代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading; namespace TcpClientTest
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
} private void FormMain_Load(object sender, EventArgs e)
{
//初始化控件
txtSendMssg.Text = "测试数据"; //打开Listener开始监听
Thread thrListener = new Thread(new ThreadStart(Listen));
thrListener.Start();
} private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
{
//强制关闭程序(强行终止Listener)
Environment.Exit();
} //发送数据
private void btnSend_Click(object sender, EventArgs e)
{
TcpClient tcpClient = new TcpClient();
//tcpClient.Connect(IPAddress.Parse("170.0.0.78"), 2014);
tcpClient.Connect(IPAddress.Parse("127.0.0.1"), ); NetworkStream ntwStream = tcpClient.GetStream();
if (ntwStream.CanWrite)
{
Byte[] bytSend = Encoding.UTF8.GetBytes(txtSendMssg.Text);
ntwStream.Write(bytSend, , bytSend.Length);
}
else
{
MessageBox.Show("无法写入数据流"); ntwStream.Close();
tcpClient.Close(); return;
} ntwStream.Close();
tcpClient.Close();
} //监听数据
private void Listen()
{
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Any, )); //不断监听端口
while (true)
{
listener.Listen();
Socket socket = listener.Accept();
NetworkStream ntwStream = new NetworkStream(socket);
StreamReader strmReader = new StreamReader(ntwStream);
Invoke(new PrintRecvMssgDelegate(PrintRecvMssg),
new object[] { strmReader.ReadToEnd() });
socket.Close();
} //程序的listener一直不关闭
//listener.Close();
} //线程内向文本框txtRecvMssg中添加字符串及委托
private delegate void PrintRecvMssgDelegate(string s);
private void PrintRecvMssg(string info)
{
txtRecvMssg.Text += string.Format("[{0}]:{1}\r\n",
DateTime.Now.ToLongTimeString(), info);
}
}
}

需要在项目上加两个TextBox名字分别为 txtSendMssg、txtRecvMssg和一个Button(名字为 btnSend

三、运行效果(效果图片见原作者文章)

在发送数据的文本框中分别输入“千山鸟飞绝”、“万径人踪灭”、“孤舟蓑笠翁”、“独钓寒江雪”四句话,输完一句话,单击一次“发送数据”按钮,就可以在接收数据里看到这四句话了。上面代码中,信息的发送时通过TcpClient连接到127.0.0.1的2014端口,信息的接收是通过Listen函数不断监听本机的2014端口实现的。从自己创建的线程中修改控件信息,用到了委托。

四、补充

1、运行时提示:由于目标计算机积极拒绝,无法连接。 127.0.0.1:2014

用 System.Net.Dns.GetHostAddresses("localhost")[1].ToString(); 取得的也是127.0.0.1

参考:https://blog.csdn.net/u010784236/article/details/51820284 也与我的情况不一样。

想想我是在局域网中,用ipconfig /all 找到自己的ip  192.168.3.5 替换  127.0.0.1 添加防火墙规则,仍不行。关闭防火墙,还不行。

(如何获得IP,还可参考:https://blog.csdn.net/fwj380891124/article/details/18214145)

正准备放弃时,看到 https://blog.csdn.net/fengzheng22/article/details/17266105 其中有一句:

需要你用tcpclient访问的IP的端口正在被监听,否则就会显示积极拒绝,不是看他是否被占用,要看他是否在监听

想想我是直接整体复制的代码,不是双击窗体后单独写的formMain_load代码。而服务端应该是在formMain_load时开始监听。

于是重新修改代码,使得formMain_load时先运行服务端监听的代码。重新生成并运行,正常。这个错误太低级。

如果在局域网两台电脑上分别运行客户端和服务端,要确保能ping通,检查防火墙规则。参考这里:https://jingyan.baidu.com/article/a65957f4f557cb24e67f9ba6.html

2、另外,这里还有个例子:https://www.jb51.net/article/130148.htm

3、参考:https://www.cnblogs.com/straight/articles/7660889.html

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。

如果作为一个服务器,在调用socket()、bind()之后就会调用listen()来监听这个socket,如果客户端这时调用connect()发出连接请求,服务器端就会接收到这个请求。

isten函数的第一个参数即为要监听的socket描述字,第二个参数为相应socket可以排队的最大连接个数。socket()函数创建的socket默认是一个主动类型的,listen函数将socket变为被动类型的,等待客户的连接请求。

TCP服务器端依次调用socket()、bind()、listen()之后,就会监听指定的socket地址了。TCP客户端依次调用socket()、connect()之后就向TCP服务器发送了一个连接请求。TCP服务器监听到这个请求之后,就会调用accept()函数取接收请求,这样连接就建立好了。之后就可以开始网络I/O操作了,即类同于普通文件的读写I/O操作。

4、TCP协议三次握手过程分析 参考:http://www.cnblogs.com/rootq/articles/1377355.html

5、C# TCP多线程服务器示例 参考:https://www.cnblogs.com/zhangxiaoyong/p/6486311.html

6. C# socket端口复用-多主机头绑定 参考:https://www.cnblogs.com/viewcozy/p/4666137.html

7、定时执行、一对多  参考:  http://www.cnblogs.com/chenxizhang/archive/2011/09/10/2172994.html

8、在同步模式中,在服务器上使用Accept方法接入连接请求,而在客户端则使用Connect方法来连接服务器。相对地,在异步模式下,服务器可以使用BeginAccept方法和EndAccept方法来完成连接到客户端的任务,在客户端则通过BeginConnect方法和EndConnect方法来实现与服务器的连接。  参考:http://www.cnblogs.com/sunev/archive/2012/08/07/2625688.html

9、C#的IPAddress IPEndPoint  参考 https://www.cnblogs.com/2Yous/p/5797592.html

简单的C#TCP协议收发数据示例的更多相关文章

  1. C# Tcp协议收发数据

    运行这个程序前需要先关闭Windows防火墙,Win7系统关闭防火墙的方法是在控制面板的“控制面板\系统和安全\Windows 防火墙\自定义设置”路径中,将“家庭或工作(专用)网络位置设置”和“公用 ...

  2. C# Tcp协议收发数据(TCPClient发,Socket收)

    转载自:http://www.cnblogs.com/WTFly/p/5340617.html 运行这个程序前需要先关闭Windows防火墙,Win7系统关闭防火墙的方法是在控制面板的"控制 ...

  3. Java基础知识强化之网络编程笔记06:TCP之TCP协议发送数据 和 接收数据

    1. TCP协议发送数据 和 接收数据 TCP协议接收数据:• 创建接收端的Socket对象• 监听客户端连接.返回一个对应的Socket对象• 获取输入流,读取数据显示在控制台• 释放资源 TCP协 ...

  4. c# tcp协议发送数据

    private void tcp_send(string data)//tcp协议转发数据 { TcpClient tcpClient = new TcpClient(); tcpClient.Con ...

  5. 为什么MOBA、“吃鸡”游戏不推荐用tcp协议——实测数据

    欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯云游戏行业资深架构师 余国良 MOBA类和"吃鸡"游戏为什么对网络延迟要求高? 我们知道,不同类型的游戏因为玩法. ...

  6. python网络编程——使用UDP、TCP协议收发信息

    UDP UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送. UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内. UDP ...

  7. Java基础之UDP协议和TCP协议简介及简单案例的实现

    写在前面的废话:马上要找工作了,做了一年的.net ,到要找工作了发现没几个大公司招聘.net工程师,真是坑爹呀.哎,java就java吧,咱从头开始学呗,啥也不说了,玩命撸吧,我真可怜啊. 摘要: ...

  8. python中TCP协议中的粘包问题

    TCP协议中的粘包问题 1.粘包现象 基于TCP实现一个简易远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() s ...

  9. TCP带外数据

    传输层协议使用带外数据(out-of-band,OOB)来发送一些重要的数据,如果通信一方有重要的数据需要通知对方时,协议能够将这些数据快速地发送到对方.为了发送这些数据,协议一般不使用与普通数据相同 ...

随机推荐

  1. mybatis笔记01

    目录 1. Mybatis的介绍 2. 使用JDBC编码的分析 2.1 准备 2.3 程序代码 2.4 JDBC问题 3. Mybatis架构 4. Mybatis入门程序 4.1 mybatis下载 ...

  2. C#设计模式之六适配器模式(Adapter Pattern)【结构型】

    一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题,那[ ...

  3. Spring Data REST API集成Springfox、Swagger

    原文: Documenting a Spring Data REST API with Springfox and Swagger 使用Spring Date REST,你可以迅速为Spring Da ...

  4. JS隐藏号码中间4位

    function resetPhone(phone) { var str = String(phone) var len = str.length; var prev,next; if (len &g ...

  5. LNMP环境下安装Redis,以及php的redis扩展

    1.下载 sudo wget http://download.redis.io/releases/redis-4.0.9.tar.gz 2.解压 sudo tar zvxf redis-4.0.9.t ...

  6. Django的模板系统

    一.语法 关于模板渲染只需要记住两种特殊符号(语法): {{ }} 和 {% %}  (变量相关用{{ }}  逻辑相关用{% %}) 二.变量 在Django的模板语言中按照{{ 变量名 }}来使用 ...

  7. CSS超全笔记(适合新手入门)

    CSS CSS初识 CSS(Cascading Style Sheets) 美化样式 CSS通常称为CSS样式表或层叠样式表(级联样式表),主要用于设置HTML页面中的文本内容(字体.大小.对齐方式等 ...

  8. python 标准类库-并行执行之subprocess-子进程管理

    标准类库-并行执行之subprocess-子进程管理 by:授客QQ:1033553122 1.使用subprocess模块 以下函数是调用子进程的推荐方法,所有使用场景它们都能处理.也可用Popen ...

  9. Android为TV端助力 切换fragment的两种方式

    使用add方法切换时:载入Fragment1Fragment1 onCreateFragment1 onCreateViewFragment1 onStartFragment1 onResume用以下 ...

  10. java基础(一)---数据类型&Math方法&强制转换

    数据类型及各种Math类方法 public class HelloWorld { public static void main(String args[]) { //各种数据类型的熟悉掌握,强制类型 ...