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,
SocketType.Stream,
ProtocolType.Tcp );
IPEndPoint endPoint = new IPEndPoint( IPAddress.Any, 5678 );
socket.Bind( endPoint );
socket.Listen( 100 );
Socket acceptSocket = socket.Accept();
byte[] buffer = new byte[ 100 ];
acceptSocket.Receive( buffer );
for( int i = 0; i < buffer.Length; i++ ) {
Console.Write( buffer[i].ToString() );
}
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 );
socket.Connect( "127.0.0.1", 5678 );
byte[] buffer = new byte[ 100 ];
for( int i = 0; i < 100; i++ ) {
buffer[i] = (byte)i;
}
socket.Send( buffer );
byte[] ReceiveBuffer = new byte[ 100 ];
socket.Receive( ReceiveBuffer );
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 );
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 );
,发现返回值为:已经接收的长度。(一般情况下,如果发送的长度等于接收的长度,并且发送是一次性发送完的不会有接收不满的情况)可以利用这个返回值,来保证接收到固定长度才停止接收。