TCP协议发送和接受文本消息
来源:互联网 发布:证书服务器开放的端口 编辑:程序博客网 时间:2024/06/05 02:28
引用总结:
对于TCP协议我不想说太多东西,这属于大学课程,又涉及计算机科学,而我不是“学院派”,对于这部分内容,我觉得作为开发人员,只需要掌握与程序相关的概念就可以了,不需要做太艰深的研究。
我们首先知道TCP是面向连接的,它的意思是说两个远程主机(或者叫进程,因为实际上远程通信是进程之间的通信,而进程则是运行中的 程序),必须首先进行一个握手过程,确认连接成功,之后才能传输实际的数据。比如说进程A想将字符串“It's a fine day today”发给进程B,它首先要建立连接。在这一过程中,它首先需要知道进程B的位置(主机地址和端口号)。随后发送一个不包含实际数据的请求报文,我 们可以将这个报文称之为“hello”。如果进程B接收到了这个“hello”,就向进程A回复一个“hello”,进程A随后才发送实际的数据 “It's a fine day today”。
关于TCP第二个需要了解的,就是它是全双工的。意思是说如果两个主机上的进程(比如进程A、进程B),一旦建立好连接,那么数据就既可以由A流向B,也可以由B流向A。除此以外,它还是点对点的,意思是说一个TCP连接总是两者之间的,在发送中,通过一个连接将数据发给多个接收方是不可能的。TCP还有一个特性,就是称为可靠的数据传输,意思是连接建立后,数据的发送一定能够到达,并且是有序的,就是说发的时候你发了ABC,那么收的一方收到的也一定是ABC,而不会是BCA或者别的什么。
编程中与TCP相关的最重要的一个概念就是套接字。我们应该知道网络七层协议,如果我们将上面的应用程、表示层、会话层笼统地算作一 层(有的教材便是如此划分的),那么我们编写的网络应用程序就位于应用层,而大家知道TCP是属于传输层的协议,那么我们在应用层如何使用传输层的服务呢 (消息发送或者文件上传下载)?大家知道在应用程序中我们用接口来分离实现,在应用层和传输层之间,则是使用套接字来进行分离。它就像是传输层为应用层开 的一个小口,应用程序通过这个小口向远程发送数据,或者接收远程发来的数据;而这个小口以内,也就是数据进入这个口之后,或者数据从这个口出来之前,我们 是不知道也不需要知道的,我们也不会关心它如何传输,这属于网络其它层次的工作。
--------------------------------------------------------------------------
对于TCP协议发送和接受消息,三种常用的方法:socket、封装了socket的tcplistensr tcpclient、更高级封装的streamreader streamwriter,socket是万能的,最灵活,同时工作量也最大,后面会提到要考虑消息界限的问题。
用高级类来实现TCP通信,client和server都在同一台电脑上
服务器端代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Net;//using System.Threading;using System.IO;namespace ConsoleServer{ class Program { static void Main(string[] args) { IPEndPoint IpEnd = new IPEndPoint(IPAddress.Any,8500); TcpListener ServerListener = new TcpListener(IpEnd); ServerListener.Start(); Console.WriteLine("Server is running"); TcpClient remoteclient = ServerListener.AcceptTcpClient(); Console.WriteLine("{0}----->{1}", remoteclient.Client.LocalEndPoint, remoteclient.Client.RemoteEndPoint); while(true) { try { NetworkStream ns = remoteclient.GetStream(); StreamReader SR = new StreamReader(ns); StreamWriter SW = new StreamWriter(ns); //写数据给客户端 byte[] dafa = new byte[100]; string welcomeA = "welcome to my test server A"; string welcomeB = "welcome to my test server B"; string welcomeC = "welcome to my test server C"; //dafa = ASCIIEncoding.ASCII.GetBytes(welcomeA); //从客户端读取数据 int buflen = remoteclient.Available; byte[] buffer = new byte[1024]; ns.Read(buffer, 0, buflen); string remotecommand = System.Text.ASCIIEncoding.ASCII.GetString(buffer).Substring(0, buflen); //stream readline //string remotecommand = SR.ReadLine(); Console.WriteLine("receive:"+remotecommand); //Console.ReadLine(); switch(remotecommand) { case "A": dafa = ASCIIEncoding.ASCII.GetBytes(welcomeA); //SW.WriteLine(welcomeA); //SW.Flush(); break; case"B": dafa = ASCIIEncoding.ASCII.GetBytes(welcomeB); //SW.WriteLine(welcomeB); //SW.Flush(); break; case"C": dafa = ASCIIEncoding.ASCII.GetBytes(welcomeC); //SW.WriteLine(welcomeC); //SW.Flush(); break; } ns.Write(dafa, 0, dafa.Length); } catch (Exception ex) { Console.WriteLine("connect error"+ex.Message); return; } } /*Q键退出 Console.WriteLine("\n\nQ键退出"); ConsoleKey key; do{ key = Console.ReadKey().Key; }while(key!=ConsoleKey.Q); */ } }}
客户端代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;//using System.Net;using System.IO;using System.Net.Sockets;namespace ConsoleClient{ class Program { static void Main(string[] args) { Console.WriteLine("client is running"); /* try { for (int i = 1; i < 5; i++) { TcpClient client = new TcpClient(); client.Connect("localhost", 8500); Console.WriteLine("{0}----->{1}", client.Client.LocalEndPoint, client.Client.RemoteEndPoint); NetworkStream ns = client.GetStream(); Byte[] buffer = new Byte[1024]; string data = "this is test"; buffer = ASCIIEncoding.ASCII.GetBytes(data); ns.Write(buffer,0,data.Length); Console.WriteLine("send:"+data+"\n"); } } catch(Exception ex) { Console.WriteLine("connect error"+ex.Message); //return; } */ TcpClient clienttcp = new TcpClient(); clienttcp.Connect("localhost", 8500); Console.WriteLine("{0}----->{1}", clienttcp.Client.LocalEndPoint, clienttcp.Client.RemoteEndPoint); NetworkStream nstcp = clienttcp.GetStream(); StreamReader SR = new StreamReader(nstcp); StreamWriter SW = new StreamWriter(nstcp); while (true) { Random rd = new Random(); byte da = (byte)rd.Next(65, 68); byte[] readda = new byte[1024]; readda[0] = da; nstcp.Write(readda,0,1); //string str = ASCIIEncoding.ASCII.GetString(readda).Substring(0,1); //Console.WriteLine("send:"+str); //SW.WriteLine(str); //SW.Flush(); //Console.ReadLine(); //Byte[] buffer = new Byte[1024]; //string data = "this is test"; //buffer = ASCIIEncoding.ASCII.GetBytes(data); //nstcp.Write(buffer, 0, data.Length); //Console.WriteLine("send:"+data); int datalen = clienttcp.Available; byte[]receivedata = new byte[2048]; nstcp.Read(receivedata,0,datalen); //string rcdata = SR.ReadLine(); string rcdata = ASCIIEncoding.ASCII.GetString(receivedata).Substring(0,datalen); Console.WriteLine("receive:"+rcdata); } /* Q键退出 Console.WriteLine("\n\nQ键退出"); ConsoleKey key; do { key = Console.ReadKey().Key; }while(key!=ConsoleKey.Q); */ } }}
在同一台电脑上运行结果,会出现接受到信息为空或者把两次信息当一次来接受的情况
下面用类StreamReader和StreamWriter来实现:
服务器端代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Net;//using System.Threading;using System.IO;namespace ConsoleServer{ class Program { static void Main(string[] args) { IPEndPoint IpEnd = new IPEndPoint(IPAddress.Any,8500); TcpListener ServerListener = new TcpListener(IpEnd); ServerListener.Start(); Console.WriteLine("Server is running"); TcpClient remoteclient = ServerListener.AcceptTcpClient(); Console.WriteLine("{0}----->{1}", remoteclient.Client.LocalEndPoint, remoteclient.Client.RemoteEndPoint); while(true) { try { NetworkStream ns = remoteclient.GetStream(); StreamReader SR = new StreamReader(ns); StreamWriter SW = new StreamWriter(ns); //写数据给客户端 //byte[] dafa = new byte[100]; string welcomeA = "welcome to my test server A"; string welcomeB = "welcome to my test server B"; string welcomeC = "welcome to my test server C"; //dafa = ASCIIEncoding.ASCII.GetBytes(welcomeA); //从客户端读取数据 //int buflen = remoteclient.Available; //byte[] buffer = new byte[1024]; //ns.Read(buffer, 0, buflen); //string remotecommand = System.Text.ASCIIEncoding.ASCII.GetString(buffer).Substring(0, buflen); //stream readline string remotecommand = SR.ReadLine(); Console.WriteLine("receive:"+remotecommand); //Console.ReadLine(); switch(remotecommand) { case "A": //dafa = ASCIIEncoding.ASCII.GetBytes(welcomeA); SW.WriteLine(welcomeA); SW.Flush(); break; case"B": //dafa = ASCIIEncoding.ASCII.GetBytes(welcomeB); SW.WriteLine(welcomeB); SW.Flush(); break; case"C": //dafa = ASCIIEncoding.ASCII.GetBytes(welcomeC); SW.WriteLine(welcomeC); SW.Flush(); break; } //ns.Write(dafa, 0, dafa.Length); } catch (Exception ex) { Console.WriteLine("connect error"+ex.Message); return; } } /*Q键退出 Console.WriteLine("\n\nQ键退出"); ConsoleKey key; do{ key = Console.ReadKey().Key; }while(key!=ConsoleKey.Q); */ } }}
客户端代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;//using System.Net;using System.IO;using System.Net.Sockets;namespace ConsoleClient{ class Program { static void Main(string[] args) { Console.WriteLine("client is running"); /* try { for (int i = 1; i < 5; i++) { TcpClient client = new TcpClient(); client.Connect("localhost", 8500); Console.WriteLine("{0}----->{1}", client.Client.LocalEndPoint, client.Client.RemoteEndPoint); NetworkStream ns = client.GetStream(); Byte[] buffer = new Byte[1024]; string data = "this is test"; buffer = ASCIIEncoding.ASCII.GetBytes(data); ns.Write(buffer,0,data.Length); Console.WriteLine("send:"+data+"\n"); } } catch(Exception ex) { Console.WriteLine("connect error"+ex.Message); //return; } */ TcpClient clienttcp = new TcpClient(); clienttcp.Connect("localhost", 8500); Console.WriteLine("{0}----->{1}", clienttcp.Client.LocalEndPoint, clienttcp.Client.RemoteEndPoint); NetworkStream nstcp = clienttcp.GetStream(); StreamReader SR = new StreamReader(nstcp); StreamWriter SW = new StreamWriter(nstcp); while (true) { Random rd = new Random(); byte da = (byte)rd.Next(65, 68); byte[] readda = new byte[1024]; readda[0] = da; //nstcp.Write(readda,0,1); string str = ASCIIEncoding.ASCII.GetString(readda).Substring(0,1); //Console.WriteLine("send:"+str); SW.WriteLine(str); SW.Flush(); //Console.ReadLine(); //Byte[] buffer = new Byte[1024]; //string data = "this is test"; //buffer = ASCIIEncoding.ASCII.GetBytes(data); //nstcp.Write(buffer, 0, data.Length); //Console.WriteLine("send:"+data); //int datalen = clienttcp.Available; //byte[]receivedata = new byte[2048]; //nstcp.Read(receivedata,0,datalen); string rcdata = SR.ReadLine(); //string rcdata = ASCIIEncoding.ASCII.GetString(receivedata).Substring(0,datalen); Console.WriteLine("receive:"+rcdata); } /* Q键退出 Console.WriteLine("\n\nQ键退出"); ConsoleKey key; do { key = Console.ReadKey().Key; }while(key!=ConsoleKey.Q); */ } }}运行结果避免了消息边界的问题产生
- TCP协议发送和接受文本消息
- ActiveMQ - tcp 协议发送消息
- kafka消息发送和消息接受
- qt 写的tcp客户端程序实现简单的连接接受和发送消息
- vc发送和接受组合键消息
- Android Broadcast发送和接受消息
- android handle 消息发送和接受!!!!!
- 接受文本消息解析
- TCP接受发送示例
- XMPP接受发送消息
- 使用ActiveMQ发送和接受消息(1)
- weblogic中使用jms发送和接受消息
- 如何使用activemq jms发送和接受消息
- java远程连接ibm mq实现发送和接受消息
- Java中通过UDP协议发送和接受数据
- Java中通过UDP协议发送和接受数据
- C# tcp发送消息和传输文件
- qt写的一个简单的tcp服务器程序,可以接受消息发送数据
- 关于编写通用API库的灵活、简洁与方便性之间的矛盾
- Android两行代码搞定ViewPager的过渡动画
- 两个editText相互监听的死循环问题
- 关于apktool反编译出错Error occured at code address 0的解决办法
- Ubuntu,Mac安装go
- TCP协议发送和接受文本消息
- Android学习-JAVA基础 (一)
- Android中Fragment添加容易遇到的问题
- API测试利器——Postman(1. 安装和启动)
- vs2008 warning4390
- HTTP协议详解
- 正则表达式
- Ubuntu14.04安装nginx稳定版本步骤
- Activity的启动模式