ソケットネットワークプログラミング(TCP / IP /ポート/タイプ)及び実施例C#ソケットネットワークプログラミングの記事エッセンス

オリジナル:ソケットネットワークプログラミングのC#のパートエッセンス

編集者:魏レンの雨

  私たちは、ソケットプログラミングを説明する前に、いくつかの密接に関連し、ソケットプログラミングの概念を見てみましょう。

  1. TCP / IP階層モデル

    もちろん、ここで我々は唯一の重要な4を議論します

       01は、アプリケーション層(アプリケーション):アプリケーション層は、いくつかの基本的な同一のシステム・レベルのTCP / IPアプリケーションとアプリケーションプロトコルが存在し、非常に広い概念であります

多くのエンタープライズアプリケーション、およびインターネットアプリケーションもあります。httpプロトコルは、アプリケーション層で動作します。

       02、トランスポート層(Tanspot):UDPとTCPトランスポート層、ほとんどUDPパケットチェック、しばらくTCP含みます

転送保証を提供します。

      03、ネットワーク層(Netwok):ネットワーク層プロトコルは、ICMP、IGMP、RIP、OSPF、IP(V4、V6)などを含む一連のプロトコル、から成ります。

      04、リンク層(リンク)も、物理データ・ネットワーク・インターフェース層として知られている、メッセージの送信を担当します。

   その後、我々は図レベルのモデルTCPを見て

 

     上の図からわかるように、アプリケーションは、TCPヘッダの前に、アプリケーション層、トランスポート層で動作プラスデータに

一緒にネットワーク層のIPヘッダとデータリンク層フレームを有します。

   2、ポート

    ポート番号の範囲:0〜65535、それは65536の合計数を表すことができます。

   ポート番号3つのに分けることができるカテゴリ

  0から1023年まで、彼らはしっかりといくつかのサービスで(結合)バインドされている:(1)ポート(WellKnownPorts)を認識しました。

これらのポートは、通常、サービス契約の明確なコミュニケーションです。たとえば、次のように、事実上、常にHTTP通信80ポート。

  (2)登録ポート(RegisteredPorts):1024から49151から。彼らは、いくつかのサービスに緩く結合しています。

これらのポートにバインドされた多くのサービスがあることを、これらのポートはまた、多くの他の目的のために使用します。

たとえば:多くのシステムでは、1024年の初め頃から動的ポートを扱います。

  (3)動的および/またはプライベートポート(Dynamicand / orPrivatePorts):49,152から65,535まで。理論的には、これらのサービス用のポートを割り当てられるべきではありません。

実際には、マシンは通常、以降1024年からの動的ポート割り当てです。

3.TCPとUDPパケット

  図と下のTCPおよびUDPパケットを見てください。

 

      図から、我々は、TCPとUDPチェックサムの両方でそれを見ることができますが、UDPパケットには、一般的にチェックサムを使用していません、

これは、データ伝送を高速化することができるが、データの精度が影響を受ける可能性があります。すなわち、TCPプロトコルのチェックサムで、データ伝送の精度を確保するためです。

3.Socket

     ソケットは、プログラムは、オペレーティングシステムのコンポーネントにソケット、ソケットの等価を介して通信する、二つの部分のIPアドレスとポート番号を含みます。

プロセス間通信機構としてソケット、一般に「ソケット」と呼ばは、通信リンクのIPアドレスとポート番号は、ハンドルで説明するために使用されます。端的に言えば、それは二つのプログラムと通信することです。

ライフケース比較:

      ソケット通信は人生コールの場合との間で比較することができます。すべてのユーザーは、コールの前に、最初は電話を占有するために、

、他のコールをダイヤルした後、固定されたソケットがあり、他の側に相当し、互いの番号を知っていると同時に、ソケットと同等のものを適用します

発行された接続要求に対応します。相手が存在し、アイドル場合は、受話器を持ち上げ、次の2つの側面を呼び出すことができます。コールの両側に、

これは、1つの方向で、電話信号が電話信号から受信した他のプロセスは、にデータを送信し、ソケットのソケットからデータを受信するために対応します。

呼び出しの後、閉じられたソケットに対応する電話パーティーハングは、取り消さ接続します。

     注:2台のコンピュータ間通信におけるソケットだけではなく、また、同じコンピュータ上の2つのプログラム間の通信を行うことができます。

4、ポート前進(深いです)

    コンピュータのIPアドレスを介してネットワークを決定した後、コンピューター上のサービスを提供するために、多くのアプリケーションを提供することができ、各アプリケーションはポートに対応しています。

インターネットでは、一般的にいくつかのサービスを提供しながら、各サービスは、ソケットを開くために、サービスのソフトウェアよりも多くを実行する、多くのそのようなホストがあります

そして、ポートにバインドされている、異なるサービスに対応した別のポート(アプリケーション)

    例:HTTP 25個のポートを使用してSMTPポート21を使用してポート80、FTPを使用して

5.Socket分類

     ソケット主に2つのタイプがあります。

  1. ストリーミングソケット

          これは、接続指向サービスのTCPアプリケーション、セキュリティでの接続指向のソケットであるが、非効率的

     2、データグラムソケット

          ソケットは、安全でないコネクションに対応するコネクションレスUDPサービスアプリケーション、が、高効率であり、

 6.ソケットの一般的なアプリケーションモード(サーバーとクライアント)

     ソケットサーバー(少なくとも2)

        クライアントの接続要求を受信するための責任(が、クライアントとの通信のための責任を負いません)01.

       成功したクライアント接続を受信した各ソケット02は、複合体は、サーバの通信に対応する生成されます

          クライアント接続を受信すると021を作成します

         対応ソケットサーバー側を作成するために、クライアント要求の成功した各接続用022(およびクライアント通信のために責任があります)

    クライアントソケット

  1. あなたはに接続するには、サーバーのアドレスとポートを指定する必要があります。
  2. TCP接続を介してSocketオブジェクトを作成するには、サーバー側を初期化するには

 

      マップでは、我々はそれを見ることができ、すべてのサーバーの最初のソケットは、監視のために責任がある作成し、クライアントがソケット指定されたポートを介してサーバーに接続し、

最後に、サーバーは、責任とクライアントの通信ソケットを作成し、接続を介してクライアントに耳を傾け、ソケットを監視する責任があります。

ここでは、ソケットより具体的な通信プロセスを見てみましょう。

ソケット通信プロセス

  サーバー側:

    01、ソケットに適用されます

    IPアドレスとポートにバインドされた02、

    03は、オープンリスニングは、接続の受信を待機し

  クライアント:

    01、ソケットに適用されます

   02、サーバー(指定したIPアドレスとポート番号)に接続します

   サーバが接続要求を受信した後、新しいソケット(1024よりも大きいポート)接続を確立し、クライアントと通信するために、オリジナルの継続リスニングのリスニングソケットを生成します。

  注意:ソケットコミュニケーションズは、作成し、オペレーティングシステムを無制限に作成する責任を負うことはできません。

 7.Socketコンストラクタ

    Public Socket(AddressFamily addressFamily,SocketType  socketType,ProtocolType  protocolTYpe)

    AddressFamily:指定Socket用来解析地址的寻址方案。例如:InterNetWork指示当Socket使用一个IP版本4地址连接

   SocketType:定义要打开的Socket的类型

   Socket类使用ProtocolType枚举向Windows  Sockets  API通知所请求的协议

注意:

   1,端口号必须在 1 和 65535之间,最好在1024以后。

   2,要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。

如:

IPAddress addr = IPAddress.Parse("127.0.0.1");

IPEndPoint endp = new IPEndPoint(addr,,9000);

         服务端先绑定:serverWelcomeSocket.Bind(endp)

         客户端再连接:clientSocket.Connect(endp)

   3,一个Socket一次只能连接一台主机

   4,Socket关闭后无法再次使用

  5,每个Socket对象只能与一台远程主机连接。如果你想连接到多台远程主机,你必须创建多个Socket对象。

8.Socket常用类和方法

  相关类:

   IPAddress:包含了一个IP地址

   IPEndPoint:包含了一对IP地址和端口号

 方法:

   Socket():创建一个Socket

   Bind():绑定一个本地的IP和端口号(IPEndPoint)

   Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量

   Connect():初始化与另一个Socket的连接

   Accept():接收连接并返回一个新的Socket

   Send():输出数据到Socket

   Receive():从Socket中读取数据

   Close():关闭Socket,销毁连接

  接下来,我们同一个简单的服务器和客户端通信的案例,来看下Sokcet的具体用法,效果图如下:

 

关键代码:

服务器端代码:

复制代码
复制代码
  1 private void Form1_Load(object sender, EventArgs e)
  2 
  3         {
  4 
  5             Control.CheckForIllegalCrossThreadCalls = false;
  6 
  7         }
  8 
  9  
 10 
 11         private void btnListen_Click(object sender, EventArgs e)
 12 
 13         {
 14 
 15             //ip地址
 16 
 17             IPAddress ip = IPAddress.Parse(txtIP.Text);
 18 
 19            // IPAddress ip = IPAddress.Any;
 20 
 21             //端口号
 22 
 23             IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));
 24 
 25             //创建监听用的Socket
 26 
 27             /*
 28 
 29              * AddressFamily.InterNetWork:使用 IP4地址。
 30 
 31 SocketType.Stream:支持可靠、双向、基于连接的字节流,而不重复数据。此类型的 Socket 与单个对方主机进行通信,
并且在通信开始之前需要远程主机连接。Stream 使用传输控制协议 (Tcp) ProtocolType 和 InterNetworkAddressFamily。 32 33 ProtocolType.Tcp:使用传输控制协议。 34 35 */ 36 37 //使用IPv4地址,流式socket方式,tcp协议传递数据 38 39 Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 40 41 //创建好socket后,必须告诉socket绑定的IP地址和端口号。 42 43 //让socket监听point 44 45 try 46 47 { 48 49 //socket监听哪个端口 50 51 socket.Bind(point); 52 53 //同一个时间点过来10个客户端,排队 54 55 socket.Listen(10); 56 57 ShowMsg("服务器开始监听"); 58 59 Thread thread = new Thread(AcceptInfo); 60 61 thread.IsBackground = true; 62 63 thread.Start(socket); 64 65 } 66 67 catch (Exception ex) 68 69 { 70 71 72 73 ShowMsg(ex.Message); 74 75 } 76 77 } 78 79 //记录通信用的Socket 80 81 Dictionary<string,Socket> dic=new Dictionary<string, Socket>(); 82 83 // private Socket client; 84 85 void AcceptInfo(object o) 86 87 { 88 89 Socket socket = o as Socket; 90 91 while (true) 92 93 { 94 95 //通信用socket 96 97 try 98 99 { 100 101 //创建通信用的Socket 102 103 Socket tSocket = socket.Accept(); 104 105 string point = tSocket.RemoteEndPoint.ToString(); 106 107 //IPEndPoint endPoint = (IPEndPoint)client.RemoteEndPoint; 108 109 //string me = Dns.GetHostName();//得到本机名称 110 111 //MessageBox.Show(me); 112 113 ShowMsg(point + "连接成功!"); 114 115 cboIpPort.Items.Add(point); 116 117 dic.Add(point, tSocket); 118 119 //接收消息 120 121 Thread th = new Thread(ReceiveMsg); 122 123 th.IsBackground = true; 124 125 th.Start(tSocket); 126 127 } 128 129 catch (Exception ex) 130 131 { 132 133 ShowMsg(ex.Message); 134 135 break; 136 137 } 138 139 } 140 141 } 142 143 //接收消息 144 145 void ReceiveMsg(object o) 146 147 { 148 149 Socket client = o as Socket; 150 151 while (true) 152 153 { 154 155 //接收客户端发送过来的数据 156 157 try 158 159 { 160 161 //定义byte数组存放从客户端接收过来的数据 162 163 byte[] buffer = new byte[1024 * 1024]; 164 165 //将接收过来的数据放到buffer中,并返回实际接受数据的长度 166 167 int n = client.Receive(buffer); 168 169 //将字节转换成字符串 170 171 string words = Encoding.UTF8.GetString(buffer, 0, n); 172 173 174 175 ShowMsg(client.RemoteEndPoint.ToString() + ":" + words); 176 177 } 178 179 catch (Exception ex) 180 181 { 182 183 ShowMsg(ex.Message); 184 185 break; 186 187 } 188 189 } 190 191 } 192 193 194 195 void ShowMsg(string msg) 196 197 { 198 199 txtLog.AppendText(msg+"\r\n"); 200 201 } 202 203 204 205 private void Form1_FormClosing(object sender, FormClosingEventArgs e) 206 207 { 208 209 //主窗体关闭时关闭子线程 210 211 212 213 } 214 215 //给客户端发送消息 216 217 private void btnSend_Click(object sender, EventArgs e) 218 219 { 220 221 try 222 223 { 224 225 ShowMsg(txtMsg.Text); 226 227 string ip = cboIpPort.Text; 228 229 byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); 230 231 dic[ip].Send(buffer); 232 233 // client.Send(buffer); 234 235 } 236 237 catch (Exception ex) 238 239 { 240 241 ShowMsg(ex.Message); 242 243 } 244 245 246 247 }
复制代码
复制代码

 

客户端代码:

复制代码
复制代码
  1 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  2 
  3         private void btnConnection_Click(object sender, EventArgs e)
  4 
  5         {
  6 
  7             //连接到的目标IP
  8 
  9             IPAddress ip = IPAddress.Parse(txtIP.Text);
 10 
 11             //IPAddress ip = IPAddress.Any;
 12 
 13             //连接到目标IP的哪个应用(端口号!)
 14 
 15             IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));
 16 
 17             try
 18 
 19             {
 20 
 21                 //连接到服务器
 22 
 23                 client.Connect(point);
 24 
 25                 ShowMsg("连接成功");
 26 
 27                 ShowMsg("服务器" + client.RemoteEndPoint.ToString());
 28 
 29                 ShowMsg("客户端:" + client.LocalEndPoint.ToString());
 30 
 31                 //连接成功后,就可以接收服务器发送的信息了
 32 
 33                 Thread th=new Thread(ReceiveMsg);
 34 
 35                 th.IsBackground = true;
 36 
 37                 th.Start();
 38 
 39             }
 40 
 41             catch (Exception ex)
 42 
 43             {
 44 
 45                 ShowMsg(ex.Message);
 46 
 47             }
 48 
 49         }
 50 
 51         //接收服务器的消息
 52 
 53         void ReceiveMsg()
 54 
 55         {
 56 
 57             while (true)
 58 
 59             {
 60 
 61                 try
 62 
 63                 {
 64 
 65                     byte[] buffer = new byte[1024 * 1024];
 66 
 67                     int n = client.Receive(buffer);
 68 
 69                     string s = Encoding.UTF8.GetString(buffer, 0, n);
 70 
 71                     ShowMsg(client.RemoteEndPoint.ToString() + ":" + s);
 72 
 73                 }
 74 
 75                 catch (Exception ex)
 76 
 77                 {
 78 
 79                     ShowMsg(ex.Message);
 80 
 81                     break;
 82 
 83                 }
 84 
 85             }
 86 
 87           
 88 
 89         }
 90 
 91  
 92 
 93         void ShowMsg(string msg)
 94 
 95         {
 96 
 97             txtInfo.AppendText(msg+"\r\n");
 98 
 99         }
100 
101  
102 
103         private void btnSend_Click(object sender, EventArgs e)
104 
105         {
106 
107             //客户端给服务器发消息
108 
109             if (client!=null)
110 
111             {
112 
113                 try
114 
115                 {
116 
117                    ShowMsg(txtMsg.Text);
118 
119                     byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);
120 
121                     client.Send(buffer);
122 
123                 }
124 
125                 catch (Exception ex)
126 
127                 {
128 
129                    ShowMsg(ex.Message);
130 
131                 }
132 
133             }
134 
135            
136 
137         }
138 
139  
140 
141         private void ClientForm_Load(object sender, EventArgs e)
142 
143         {
144 
145             Control.CheckForIllegalCrossThreadCalls = false;
146 
147         }
复制代码
复制代码

 

 
  1. TCP/IP层次模型

    当然这里我们只讨论重要的四层

       01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,

也有许多的企业应用和互联网应用。http协议在应用层运行。

       02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP

提供传输保证。

      03,网络层(Netwok):网络层协议由一系列协议组成,包括ICMP、IGMP、RIP、OSPF、IP(v4,v6)等。

      04,链路层(Link):又称为物理数据网络接口层,负责报文传输。

   然后我们来看下tcp层次模型图

 

     从上图中可以看出,应用程序在应用层运行,在传输层,在数据前加上了TCP头,在

网络层加上的IP头,在数据链路层加上了帧。

   2,端口

    端口号范围:0-65535,总共能表示65536个数。

   按端口号可分为3大类

  (1)公认端口(WellKnownPorts):从0到1023,它们紧密绑定(binding)于一些服务。

通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。

  (2)注册端口(RegisteredPorts):从1024到49151。它们松散地绑定于一些服务。

也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。

例如:许多系统处理动态端口从1024左右开始。

  (3)动态和/或私有端口(Dynamicand/orPrivatePorts):从49152到65535。理论上,不应为服务分配这些端口。

实际上,机器通常从1024起分配动态端口。

3.TCP和UDP报文

  下面一起来看下TCP和UDP的报文图

 

      从图中我们可以看出TCP和UDP中都有校验和,但是在UDP报文中,一般不使用校验和,

这样可以加快数据传输的速度,但是数据的准确性可能会受到影响。换句话说,Tcp协议都有校验和,为了保证传输数据的准确性。

3.Socket

     Socket包括Ip地址和端口号两部分,程序通过Socket来通信,Socket相当于操作系统的一个组件。

Socket作为进程之间通信机制,通常也称作”套接字”,用于描述IP地址和端口号,是一个通信链的句柄。说白了,就是两个程序通信用的。

生活案例对比:

      Socket之间的通信可以类比生活中打电话的案例。任何用户在通话之前,首先要占有一部电话机,

相当于申请一个Socket,同时要知道对方的号码,相当于对方有一个固定的Socket,然后向对方拨号呼叫,

相当于发出连接请求。假如对方在场并空闲,拿起 电话话筒,双方就可以进行通话了。双方的通话过程,

是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。

通话结束后,一方挂起电话机,相当于关闭socket,撤销连接。

     注意:Socket不仅可以在两台电脑之间通信,还可以在同一台电脑上的两个程序间通信。

4,端口进阶(深入)

    通过IP地址确定了网络中的一台电脑后,该电脑上可能提供很多提供服务的应用,每一个应用都对应一个端口。

在Internet上有很多这样的主机,这些主机一般运行了多个服务软件 ,同时提供几种服务,每种服务都打开一个Socket,

并绑定到一个端口上,不同的端口对应于不同的服务(应用程序)

    例如:http 使用80端口,   ftp使用21端口     smtp使用25端口

5.Socket分类

     Socket主要有两种类型:

  1. 流式Socket

          是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低

     2,数据报式Socket

          是一种无连接的Socket,对应于无连接的UDP服务应用,不安全,但效率高

 6. Socket一般应用模式(服务器端和客户端)

     服务器端的Socket(至少需要两个)

        01.一个负责接收客户端连接请求(但不负责与客户端通信)

       02.每成功接收到客户端的连接便在服务器端产生一个对应的复杂通信的Socket

          021.在接收到客户端连接时创建

         022. 为每个连接成功的客户端请求在服务器端都创建一个对应的Socket(负责和客户端通信)

    客户端的Socket

  1. 必须指定要连接的服务器地址和端口
  2. 通过创建一个Socket对象来初始化一个到服务器端的TCP连接

 

      通过上图,我们可以看出,首先服务器会创建一个负责监听的socket,然后客户端通过socket连接到服务器指定端口,

最后服务器端负责监听的socket,监听到客户端有连接过来了,就创建一个负责和客户端通信的socket。

下面我们来看下Socket更具体的通信过程:

Socket的通讯过程

  服务器端:

    01,申请一个socket

    02,绑定到一个IP地址和一个端口上

    03,开启侦听,等待接收连接

  客户端:

    01,申请一个socket

   02,连接服务器(指明IP地址和端口号)

   服务器端接收到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通信,原监听socket继续监听。

  注意:负责通信的Socket不能无限创建,创建的数量和操作系统有关。

 7.Socket的构造函数

    Public Socket(AddressFamily addressFamily,SocketType  socketType,ProtocolType  protocolTYpe)

    AddressFamily:指定Socket用来解析地址的寻址方案。例如:InterNetWork指示当Socket使用一个IP版本4地址连接

   SocketType:定义要打开的Socket的类型

   Socket类使用ProtocolType枚举向Windows  Sockets  API通知所请求的协议

注意:

   1,端口号必须在 1 和 65535之间,最好在1024以后。

   2,要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。

如:

IPAddress addr = IPAddress.Parse("127.0.0.1");

IPEndPoint endp = new IPEndPoint(addr,,9000);

         服务端先绑定:serverWelcomeSocket.Bind(endp)

         客户端再连接:clientSocket.Connect(endp)

   3,一个Socket一次只能连接一台主机

   4,Socket关闭后无法再次使用

  5,每个Socket对象只能与一台远程主机连接。如果你想连接到多台远程主机,你必须创建多个Socket对象。

8.Socket常用类和方法

  相关类:

   IPAddress:包含了一个IP地址

   IPEndPoint:包含了一对IP地址和端口号

 方法:

   Socket():创建一个Socket

   Bind():绑定一个本地的IP和端口号(IPEndPoint)

   Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量

   Connect():初始化与另一个Socket的连接

   Accept():接收连接并返回一个新的Socket

   Send():输出数据到Socket

   Receive():从Socket中读取数据

   Close():关闭Socket,销毁连接

  接下来,我们同一个简单的服务器和客户端通信的案例,来看下Sokcet的具体用法,效果图如下:

 

关键代码:

服务器端代码:

复制代码
复制代码
  1 private void Form1_Load(object sender, EventArgs e)
  2 
  3         {
  4 
  5             Control.CheckForIllegalCrossThreadCalls = false;
  6 
  7         }
  8 
  9  
 10 
 11         private void btnListen_Click(object sender, EventArgs e)
 12 
 13         {
 14 
 15             //ip地址
 16 
 17             IPAddress ip = IPAddress.Parse(txtIP.Text);
 18 
 19            // IPAddress ip = IPAddress.Any;
 20 
 21             //端口号
 22 
 23             IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));
 24 
 25             //创建监听用的Socket
 26 
 27             /*
 28 
 29              * AddressFamily.InterNetWork:使用 IP4地址。
 30 
 31 SocketType.Stream:支持可靠、双向、基于连接的字节流,而不重复数据。此类型的 Socket 与单个对方主机进行通信,
并且在通信开始之前需要远程主机连接。Stream 使用传输控制协议 (Tcp) ProtocolType 和 InterNetworkAddressFamily。 32 33 ProtocolType.Tcp:使用传输控制协议。 34 35 */ 36 37 //使用IPv4地址,流式socket方式,tcp协议传递数据 38 39 Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 40 41 //创建好socket后,必须告诉socket绑定的IP地址和端口号。 42 43 //让socket监听point 44 45 try 46 47 { 48 49 //socket监听哪个端口 50 51 socket.Bind(point); 52 53 //同一个时间点过来10个客户端,排队 54 55 socket.Listen(10); 56 57 ShowMsg("服务器开始监听"); 58 59 Thread thread = new Thread(AcceptInfo); 60 61 thread.IsBackground = true; 62 63 thread.Start(socket); 64 65 } 66 67 catch (Exception ex) 68 69 { 70 71 72 73 ShowMsg(ex.Message); 74 75 } 76 77 } 78 79 //记录通信用的Socket 80 81 Dictionary<string,Socket> dic=new Dictionary<string, Socket>(); 82 83 // private Socket client; 84 85 void AcceptInfo(object o) 86 87 { 88 89 Socket socket = o as Socket; 90 91 while (true) 92 93 { 94 95 //通信用socket 96 97 try 98 99 { 100 101 //创建通信用的Socket 102 103 Socket tSocket = socket.Accept(); 104 105 string point = tSocket.RemoteEndPoint.ToString(); 106 107 //IPEndPoint endPoint = (IPEndPoint)client.RemoteEndPoint; 108 109 //string me = Dns.GetHostName();//得到本机名称 110 111 //MessageBox.Show(me); 112 113 ShowMsg(point + "连接成功!"); 114 115 cboIpPort.Items.Add(point); 116 117 dic.Add(point, tSocket); 118 119 //接收消息 120 121 Thread th = new Thread(ReceiveMsg); 122 123 th.IsBackground = true; 124 125 th.Start(tSocket); 126 127 } 128 129 catch (Exception ex) 130 131 { 132 133 ShowMsg(ex.Message); 134 135 break; 136 137 } 138 139 } 140 141 } 142 143 //接收消息 144 145 void ReceiveMsg(object o) 146 147 { 148 149 Socket client = o as Socket; 150 151 while (true) 152 153 { 154 155 //接收客户端发送过来的数据 156 157 try 158 159 { 160 161 //定义byte数组存放从客户端接收过来的数据 162 163 byte[] buffer = new byte[1024 * 1024]; 164 165 //将接收过来的数据放到buffer中,并返回实际接受数据的长度 166 167 int n = client.Receive(buffer); 168 169 //将字节转换成字符串 170 171 string words = Encoding.UTF8.GetString(buffer, 0, n); 172 173 174 175 ShowMsg(client.RemoteEndPoint.ToString() + ":" + words); 176 177 } 178 179 catch (Exception ex) 180 181 { 182 183 ShowMsg(ex.Message); 184 185 break; 186 187 } 188 189 } 190 191 } 192 193 194 195 void ShowMsg(string msg) 196 197 { 198 199 txtLog.AppendText(msg+"\r\n"); 200 201 } 202 203 204 205 private void Form1_FormClosing(object sender, FormClosingEventArgs e) 206 207 { 208 209 //主窗体关闭时关闭子线程 210 211 212 213 } 214 215 //给客户端发送消息 216 217 private void btnSend_Click(object sender, EventArgs e) 218 219 { 220 221 try 222 223 { 224 225 ShowMsg(txtMsg.Text); 226 227 string ip = cboIpPort.Text; 228 229 byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); 230 231 dic[ip].Send(buffer); 232 233 // client.Send(buffer); 234 235 } 236 237 catch (Exception ex) 238 239 { 240 241 ShowMsg(ex.Message); 242 243 } 244 245 246 247 }
复制代码
复制代码

 

客户端代码:

复制代码
复制代码
  1 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  2 
  3         private void btnConnection_Click(object sender, EventArgs e)
  4 
  5         {
  6 
  7             //连接到的目标IP
  8 
  9             IPAddress ip = IPAddress.Parse(txtIP.Text);
 10 
 11             //IPAddress ip = IPAddress.Any;
 12 
 13             //连接到目标IP的哪个应用(端口号!)
 14 
 15             IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));
 16 
 17             try
 18 
 19             {
 20 
 21                 //连接到服务器
 22 
 23                 client.Connect(point);
 24 
 25                 ShowMsg("连接成功");
 26 
 27                 ShowMsg("服务器" + client.RemoteEndPoint.ToString());
 28 
 29                 ShowMsg("客户端:" + client.LocalEndPoint.ToString());
 30 
 31                 //连接成功后,就可以接收服务器发送的信息了
 32 
 33                 Thread th=new Thread(ReceiveMsg);
 34 
 35                 th.IsBackground = true;
 36 
 37                 th.Start();
 38 
 39             }
 40 
 41             catch (Exception ex)
 42 
 43             {
 44 
 45                 ShowMsg(ex.Message);
 46 
 47             }
 48 
 49         }
 50 
 51         //接收服务器的消息
 52 
 53         void ReceiveMsg()
 54 
 55         {
 56 
 57             while (true)
 58 
 59             {
 60 
 61                 try
 62 
 63                 {
 64 
 65                     byte[] buffer = new byte[1024 * 1024];
 66 
 67                     int n = client.Receive(buffer);
 68 
 69                     string s = Encoding.UTF8.GetString(buffer, 0, n);
 70 
 71                     ShowMsg(client.RemoteEndPoint.ToString() + ":" + s);
 72 
 73                 }
 74 
 75                 catch (Exception ex)
 76 
 77                 {
 78 
 79                     ShowMsg(ex.Message);
 80 
 81                     break;
 82 
 83                 }
 84 
 85             }
 86 
 87           
 88 
 89         }
 90 
 91  
 92 
 93         void ShowMsg(string msg)
 94 
 95         {
 96 
 97             txtInfo.AppendText(msg+"\r\n");
 98 
 99         }
100 
101  
102 
103         private void btnSend_Click(object sender, EventArgs e)
104 
105         {
106 
107             //客户端给服务器发消息
108 
109             if (client!=null)
110 
111             {
112 
113                 try
114 
115                 {
116 
117                    ShowMsg(txtMsg.Text);
118 
119                     byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);
120 
121                     client.Send(buffer);
122 
123                 }
124 
125                 catch (Exception ex)
126 
127                 {
128 
129                    ShowMsg(ex.Message);
130 
131                 }
132 
133             }
134 
135            
136 
137         }
138 
139  
140 
141         private void ClientForm_Load(object sender, EventArgs e)
142 
143         {
144 
145             Control.CheckForIllegalCrossThreadCalls = false;
146 
147         }
复制代码
复制代码

 

おすすめ

転載: www.cnblogs.com/CodeWorkerLiMing/p/11580326.html