C#培训2019-11-15 Socket 实现两个应用之间通信(相同/不同主机之间)

Socket利用TCP/IP通信方法,实现一台主机中两个应用通信,或者多台主机中应用的通信。
引用using System.Net.Sockets; using System.Net;
1、Server端设置:Server端主要是用来监听Client端是否有连接的。范例代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace Serve
{
	class Program
	{
		static void Main( string[] args )
		{
			Socket socket = new Socket(
				AddressFamily.InterNetwork,// ipv4
				SocketType.Stream,// 串流
				ProtocolType.Tcp );// tcp协议,有时候会用udp
			// serve要绑定主机的ip地址
			IPEndPoint endPoint = new IPEndPoint( IPAddress.Any, 5678 );//准备一个端口,IPAddress.Any 表示可能有双网卡,都会绑定
			socket.Bind( endPoint );

			socket.Listen( 100 );//听client连线,100表示同时可以检测100个

			//当client连线后,需要处理。只有连线时,才会执行这一步,
			//又创建一个Socket来执行数据的接受和发送
			Socket acceptSocket = socket.Accept();

			byte[] buffer = new byte[ 100 ];
			
			// 连接上以后如果没有接受到资料,就会停在这里等待,直到接受到长度为100的byte(可以选择自定义长度的重载方法)
			//可以一直resive,上一次resive完后,还是在连接状态
			//常用的是接受一个封包,要解析,接受长度是根据解析封包长度来定
			acceptSocket.Receive( buffer );

			for( int i = 0; i < buffer.Length; i++ ) {
				Console.Write( buffer[i].ToString() );
			}
			// 发送给Client数据
			byte[] SendBuffer = new byte[ 100 ];
			for( int i = 0; i < 100; i++ ) {
				SendBuffer[ i ] = (byte)(i+100);
			}
			acceptSocket.Send( SendBuffer );
			Console.ReadLine();
		}
	}
}

2、Client端设置:Client端主要是用来连接Server端,连接上后可以和Server端相互传输数据。范例代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace Client
{
	class Program
	{
		static void Main( string[] args )
		{
			Socket socket = new Socket(
				AddressFamily.InterNetwork,
				SocketType.Stream,
				ProtocolType.Tcp );
			//IPEndPoint endPoint = new IPEndPoint();
			//socket.Connect( "18.18.90.197", 5678 );//127.0.0.1是本地端连接ip,此处的端口号要与Server端口号相同,IP可以是外网ip也可以是本机ip
			socket.Connect( "127.0.0.1", 5678 );//也是可以的

			// 此时就是这socket和外部连接沟通
			byte[] buffer = new byte[ 100 ];
			for( int i = 0; i < 100; i++ ) {
				buffer[i] = (byte)i;
			}
			socket.Send( buffer );//发送给Server数据
			
			byte[] ReceiveBuffer = new byte[ 100 ];
			socket.Receive( ReceiveBuffer );//接受Server传过来的数据
			for( int i = 0; i < ReceiveBuffer.Length; i++ ) {
				Console.Write( ReceiveBuffer[ i ].ToString() );
			}
			Console.ReadLine();
		}
	}
}

3、注意事项
①当Server端接到连接后,会执行下一步动作,此时若又另一个连接过来,也会连上。因此一般会用逻辑或其他方式(线程)来单独处理每一个连接。
②查看电脑端口情况CMD代码:netstat -na
③Server端和Client端之间发送的数据只能是 byte[],若要发送字串需要编码和解码,如:
            String string1 = "测试数据123测试数据ABC";
            byte[] buffer = new byte[2048];

			//编码后才能发送字符串
            buffer = Encoding.Default.GetBytes(string1);

            Socket socket = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
            socket.Connect("127.0.0.1", 5678);
            socket.Send(buffer);
            socket.Close();
            MessageBox.Show("发送完毕");
当然同样的接受到的 byte[]也要解码成字符串,才能正常显示,如:
			byte[] buffer = new byte[ 1024 ];
			acceptSocket.Receive( buffer );
			
			// 下面就是利用Encoding.Default.GetString()方法来解码的
			Console.Write( Encoding.Default.GetString( buffer ) );
④若发送的长度较长(eg:100),接收的变量长度较短(eg:10),则会一次性接收不完,下一次遇到acceptSocket.Receive( buffer );的时候会继续接收上一次没接收完的信息,知道把上一次的完全接收完毕。(例如100长度的发送,用10长度接收,需要接收10次,而不是接收不下直接舍去。)
4、一般使用:
①解决线程调用方法传值:调用时如果需要传入参数,可以通过实例化类来避免这件事,如每次都是实例化类,在建构子中传入参数,然后定义字段。并且在建构子中开新的线程。
②解决编码后长度改变:每次编码后,用数组的CopyTo/Clone方法浅拷贝到另一个固定长度的buffer来装,这样就能保证发送的长度固定了。
③接收固定长度,为了保证每次Receive的长度为固定长度,找到方法的定义,public int Receive( byte[] buffer );,发现返回值为:已经接收的长度。(一般情况下,如果发送的长度等于接收的长度,并且发送是一次性发送完的不会有接收不满的情况)可以利用这个返回值,来保证接收到固定长度才停止接收。
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值