C#.NET通过Socket实现平行主机之间网络通讯
2010-09-30 22:46:31 来源:WEB开发网查看原图(大图)
二、通讯相关的代码
本文以Windows控制台程序为例来实现引功能。
不管是通讯服务器或者通讯客户端,本文均以一个不断运行的线程来实现对端口的侦听,将通讯相关的变量的函数做成一个类,在Program.cs中只负责初始化一些参数,然后建立通讯的线程。具体代码如下:
2.1服务器端
Program.cs:
代码
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ConsoleSocketsDemo
{
class Program
{
static void Main(string[] args)
{
int sendPicPort = 600;//发送图片的端口
int recvCmdPort = 400;//接收请求的端口开启后就一直进行侦听
SocketServer socketServerProcess = new SocketServer(recvCmdPort, sendPicPort);
Thread tSocketServer = new Thread(new ThreadStart(socketServerProcess.thread));//线程开始的时候要调用的方法为threadProc.thread
tSocketServer.IsBackground = true;//设置IsBackground=true,后台线程会自动根据主线程的销毁而销毁
tSocketServer.Start();
Console.ReadKey();//直接main里边最后加个Console.Read()不就好了。要按键才退出。
}
}
}
SocketServer.cs:
代码
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace ConsoleSocketsDemo
{
class SocketServer
{
Socket sRecvCmd;
int recvCmdPort;//接收图片请求命令
int sendPicPort;//发送图片命令
public SocketServer(int recvPort,int sendPort)
{
recvCmdPort = recvPort;
sendPicPort = sendPort;
//建立本地socket,一直对4000端口进行侦听
IPEndPoint recvCmdLocalEndPoint = new IPEndPoint(IPAddress.Any, recvCmdPort);
sRecvCmd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sRecvCmd.Bind(recvCmdLocalEndPoint);
sRecvCmd.Listen(100);
}
public void thread()
{
while (true)
{
System.Threading.Thread.Sleep(1);//每个线程内部的死循环里面都要加个“短时间”睡眠,使得线程占用资源得到及时释放
try
{
Socket sRecvCmdTemp = sRecvCmd.Accept();//Accept 以同步方式从侦听套接字的连接请求队列中提取第一个挂起的连接请求,然后创建并返回新的 Socket
sRecvCmdTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);//设置接收数据超时
sRecvCmdTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 5000);//设置发送数据超时
sRecvCmdTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, 1024); //设置发送缓冲区大小 1K
sRecvCmdTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, 1024);//设置接收缓冲区大小1K
byte[] recvBytes = new byte[1024];//开启一个缓冲区,存储接收到的信息
sRecvCmdTemp.Receive(recvBytes); //将读得的内容放在recvBytes中
string strRecvCmd = Encoding.Default.GetString(recvBytes);//
//程序运行到这个地方,已经能接收到远程发过来的命令了
//*************
//解码命令,并执行相应的操作----如下面的发送本机图片
//*************
string[] strArray = strRecvCmd.Split(';');
if (strArray[0] == "PicRequest")
{
string[] strRemoteEndPoint = sRecvCmdTemp.RemoteEndPoint.ToString().Split(':');//远处终端的请求端IP和端口,如:127.0.0.1:4000
string strRemoteIP = strRemoteEndPoint[0];
SentPictures(strRemoteIP, sendPicPort); //发送本机图片文件
recvBytes = null;
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
}
}
/// <summary>
/// 向远程客户端发送图片
/// </summary>
/// <param name="strRemoteIP">远程客户端IP</param>
/// <param name="sendPort">发送图片的端口</param>
private static void SentPictures(string strRemoteIP, int sendPort)
{
string path = "D:\\images\\";
string strImageTag = "image";//图片名称中包含有image的所有图片文件
try
{
string[] picFiles = Directory.GetFiles(path, strImageTag + "*", SearchOption.TopDirectoryOnly);//满足要求的文件个数
if (picFiles.Length == 0)
{
return;//没有图片,不做处理
}
long sendBytesTotalCounts = 0;//发送数据流总长度
//消息头部:命令标识+文件数目+……文件i长度+
string strMsgHead = "PicResponse;" + picFiles.Length + ";";
//消息体:图片文件流
byte[][] msgPicBytes = new byte[picFiles.Length][];
for (int j = 0; j < picFiles.Length; j++)
{
FileStream fs = new FileStream(picFiles[j].ToString(), FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fs);
msgPicBytes[j] = new byte[fs.Length];
strMsgHead += fs.Length.ToString() + ";";
sendBytesTotalCounts += fs.Length;
reader.Read(msgPicBytes[j], 0, msgPicBytes[j].Length);
}
byte[] msgHeadBytes = Encoding.Default.GetBytes(strMsgHead);//将消息头字符串转成byte数组
sendBytesTotalCounts += msgHeadBytes.Length;
//要发送的数据流:数据头+数据体
byte[] sendMsgBytes = new byte[sendBytesTotalCounts];//要发送的总数组
for (int i = 0; i < msgHeadBytes.Length; i++)
{
sendMsgBytes[i] = msgHeadBytes[i]; //数据头
}
int index = msgHeadBytes.Length;
for (int i = 0; i < picFiles.Length; i++)
{
for (int j = 0; j < msgPicBytes[i].Length; j++)
{
sendMsgBytes[index + j] = msgPicBytes[i][j];
}
index += msgPicBytes[i].Length;
}
//程序执行到此处,带有图片信息的报文已经准备好了
//PicResponse;2;94223;69228;
//+图片1比特流+……图片2比特流
try
{
#region 发送图片
Socket sSendPic = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse(strRemoteIP);//remoteip = "127.0.0.1"
try
{
sSendPic.Connect(ipAddress, sendPort);//连接无端客户端主机
sSendPic.Send(sendMsgBytes, sendMsgBytes.Length, 0);//发送本地图片
}
catch (System.Exception e)
{
System.Console.Write("SentPictures函数在建立远程连接时出现异常:" + e.Message);
}finally
{
sSendPic.Close();
}
#endregion
}
catch
{
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
}
}
}
更多精彩
赞助商链接