热门搜索 :
考研考公
您的当前位置:首页正文

winform通讯编程

来源:伴沃教育
Socket通讯:

public class XmlSocket {

//异步socket诊听

// Incoming data from client.从客户端传来的数据 public static string data = null;

// Thread signal.线程 用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。

public static ManualResetEvent allDone = new ManualResetEvent(false); //static void Main(string[] args) //{

// StartListening(); //}

public static void StartListening() {

// Data buffer for incoming data. 传入数据缓冲 byte[] bytes = new Byte[1024];

// Establish the local endpoint for the socket. 建立本地端口 // The DNS name of the computer

// running the listener is \"host.contoso.com\".

IPAddress ipAddress;

String ipString = ConfigurationManager.AppSettings.Get(\"SocketIP\"); if (ipString==null || ipString ==String.Empty) {

IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); ipAddress = ipHostInfo.AddressList[0]; } else {

ipAddress = IPAddress.Parse(ipString); }

int port;

String portString =

ConfigurationManager.AppSettings.Get(\"SocketPort\");

if (portString==null || portString==String.Empty) {

port = 11001; } else

{

port = int.Parse(portString); }

IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);

// Create a TCP/IP socket.

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

// Bind the socket to the local endpoint and listen for incoming connections.绑定端口和数据 try {

listener.Bind(localEndPoint); listener.Listen(100);

while (true) {

// Set the event to nonsignaled state.设置无信号状态的事件 allDone.Reset();

// Start an asynchronous socket to listen for connections.重新 启动异步连接

listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

// Wait until a connection is made before continuing.等待连接创建后继续

allDone.WaitOne(); } }

catch (Exception e) { // } }

public static void AcceptCallback(IAsyncResult ar) { try {

// Signal the main thread to continue.接受回调方法 该方法的此节向主应用程序线程发出信号,

//让它继续处理并建立与客户端的连接 allDone.Set();

// Get the socket that handles the client request.获取客户端请求句柄

Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); // Create the state object.

StateObject state = new StateObject(); state.workSocket = handler;

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); }

catch (Exception e) { // } }

///

/// 与接受回调方法一样,读取回调方法也是一个 AsyncCallback 委托。 /// 该方法将来自客户端套接字的一个或多个字节读入数据缓冲区,然后再次调用 BeginReceive 方法,直到客户端发送的数据完成为止。

/// 从客户端读取整个消息后,在控制台上显示字符串,并关闭处理与客户端的连接的服务器套接字。

///

/// IAsyncResult 委托 public static void ReadCallback(IAsyncResult ar) { try {

String content = String.Empty;

// Retrieve the state object and the handler socket创建自定义的状态对象 from the asynchronous state object.

StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket;//处理的句柄 // Read data from the client socket. 读出 int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) {

//业务代码

string result = DoSomeThing(...); String len =

Encoding.UTF8.GetBytes(result).Length.ToString().PadLeft(8, '0'); log.writeLine(len);

Send(len + result, handler); }

}

catch (Exception e) { // }

}

private static void Send(String data, Socket handler) { try {

// Convert the string data to byte data using UTF8 encoding. byte[] byteData = Encoding.UTF8.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); }

catch (Exception e) { // } }

///

/// 发送

///

///

private static void SendCallback(IAsyncResult ar) { try {

// Retrieve the socket from the state object. Socket handler = (Socket)ar.AsyncState;

// Complete sending the data to the remote device.向远端发送数据 int bytesSent = handler.EndSend(ar); StateObject state = new StateObject(); state.workSocket = handler;

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);

handler.Shutdown(SocketShutdown.Both); handler.Close(); }

catch (Exception e)

{ //

} }

public static void StopListening() {

allDone.Close(); log.close(); }

///

/// 具体处理业务的方法 ///

///

private static string DoSomething(int i) {

//具体业务代码,返回需要返回的字符串信息 }

///

/// 写日志方法 ///

/// 写入内容 public static void WriteLog(string strLog) {

//写入日志代码 }

}

/// 线程执行体,转发消息

///

/// 传递给线程执行体的用户名,用以与用户通信 private void ThreadFunc(object obj) {

//通过转发表得到当前用户套接字

Socket clientSkt = _transmit_tb[obj] as Socket; //主循环

while (true) { try

{ //接受第一个数据包。

//由于程序逻辑结构简单,所以在这里对客户机发送的第一个包内容作逐一判断, //这里的实现不够优雅,但不失为此简单模型的一个解决之道。 byte[] packetBuff = new byte[_maxPacket]; clientSkt.Receive(packetBuff);

string _str =

Encoding.Unicode.GetString(packetBuff).TrimEnd('\\0'); //如果是发给不在线好友的信息

if (_str.StartsWith(\"cmd::FriendMessage\")) {

string UserName =

_str.Substring(\"cmd::FriendMessage\".Length, 20).Trim(); string MessageS =

_str.Substring(\"cmd::FriendMessage\".Length + 20, _str.Length - \"cmd::FriendMessage\".Length - 20);

SaveMessage(obj as string, UserName, MessageS); continue; }

//如果是离线请求

if (_str.StartsWith(\"cmd::RequestLogout\")) {

_transmit_tb.Remove(obj);

UpdateFriendList((string)obj, false, \"\");

// string svrlog = string.Format(\"[系统消息]用户 {0} 在 {1} 已断开... 当前在线人数: {2}\\r\\n\\r\\n\ // Console.WriteLine(svrlog); //向所有客户机发送系统消息

//foreach (DictionaryEntry de in _transmit_tb) //{

// string _clientName = de.Key as string; // Socket _clientSkt = de.Value as Socket;

// _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog)); //}

Thread.CurrentThread.Abort(); }

//如果是请求好友列表

if (_str.StartsWith(\"cmd::RequestFriendList\")) {

SerializeFriendList(obj, clientSkt); // 将该用户不在线时的信息发送给用户

DataTable TabMessage = ReadMessage(obj as string); if (TabMessage != null) {

foreach (DataRow myrow in TabMessage.Rows) {

if (myrow[\"SendUserName\"].ToString() == \"System::Message\")

{

clientSkt.Send(Encoding.Unicode.GetBytes(myrow[\"Message\"].ToString())); } else {

clientSkt.Send(Encoding.Unicode.GetBytes(\"cmd::FriendMessage\" + myrow[\"SendUserName\"].ToString().PadRight(20, ' ') + myrow[\"Message\"].ToString())); } }

} //这里不需要再继续接受后继数据包了,跳出当前循环体。 continue; }

////如果是请求好友列表

//if (_str.StartsWith(\"cmd::RequestOnLineList\")) //{

// byte[] onlineBuff = SerializeOnlineList(); // //先发送响应信号,用户客户机的判断 //

clientSkt.Send(Encoding.Unicode.GetBytes(\"cmd::RequestOnLineList\")); // clientSkt.Send(onlineBuff);

// //这里不需要再继续接受后继数据包了,跳出当前循环体。 // continue; //} //查找用户

if (_str.StartsWith(\"Find::FindFriend\")) {

DataTable TabFind = TabUser.Clone(); DataRow [] FindRow =null ;

string UserName = _str.Substring(\"Find::FindFriend\".Length, _str.Length - \"Find::FindFriend\".Length);

if (UserName.Equals(\"Find::WhoOnLine\")) { //看谁在线

FindRow = TabUser.Select(\" ZX = 1\"); }

else//精确查找 {

FindRow = TabUser.Select(\"UserName = '\" + UserName + \"'\"); }

foreach (DataRow myrow in FindRow) {

TabFind.ImportRow(myrow); }

clientSkt.Send(Encoding.Unicode.GetBytes(\"Find::FindFriend\")); IFormatter format = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); format.Serialize(stream, TabFind); stream.Position = 0;

byte[] ret = new byte[_maxPacket]; int count = 0;

count = stream.Read(ret, 0, _maxPacket); while (count >0) {

clientSkt.Send(ret);

count = stream.Read(ret, 0, _maxPacket); }

clientSkt.Send(Encoding.Unicode.GetBytes(\"Find::FindFriendEnd\")); stream.Close(); TabFind = null;

FindRow = null; //这里不需要再继续接受后继数据包了,跳出当前循环体。

continue; } //请求添加好友

if (_str.StartsWith(\"Find::AddFriendAsk\")) {

string UserName =

_str.Substring(\"Find::AddFriendAsk\".Length, _str.Length - \"Find::AddFriendAsk\".Length);

//通过转发表查找接收方的套接字 if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(UserName)) {

Socket receiverSkt = _transmit_tb[UserName] as Socket;

receiverSkt.Send(Encoding.Unicode.GetBytes(\"Find::AddFriendAsk\" + obj as string));

}

//这里不需要再继续接受后继数据包了,跳出当前循环体。 continue; }

//回复答应添加好友

if (_str.StartsWith(\"Find::AddFriendYes\")) {

string UserName =

_str.Substring(\"Find::AddFriendYes\".Length, _str.Length - \"Find::AddFriendYes\".Length); //// 保存数据

DataTable TabmyFriend = new DataTable() ; //保存该用户

TabmyFriend.ReadXml(MyPath + \"\\\\UserFriend\\\\\" + obj as string + \".xml\");

DataRow newRow = TabmyFriend.NewRow(); newRow[\"UserName\"] = UserName; TabmyFriend.Rows.Add(newRow);

TabmyFriend.WriteXml(MyPath + \"\\\\UserFriend\\\\\" + obj as string + \".xml\", XmlWriteMode.WriteSchema, false); //保存其好友

TabmyFriend = new DataTable();

TabmyFriend.ReadXml(MyPath + \"\\\\UserFriend\\\\\" + UserName + \".xml\");

DataRow newRow1 = TabmyFriend.NewRow(); newRow1[\"UserName\"] = obj as string; TabmyFriend.Rows.Add(newRow1);

TabmyFriend.WriteXml(MyPath + \"\\\\UserFriend\\\\\" + UserName + \".xml\", XmlWriteMode.WriteSchema, false); TabmyFriend = null;

SerializeFriendList(obj, clientSkt); //\"开始\"按钮事件

private void button1_Click(object sender, System.EventArgs e) {

//取得预保存的文件名

string fileName=textBox3.Text.Trim();

//远程主机

string hostName=textBox1.Text.Trim();

//端口

int port=Int32.Parse(textBox2.Text.Trim());

//得到主机信息

IPHostEntry ipInfo=Dns.GetHostByName(hostName);

//取得IPAddress[]

IPAddress[] ipAddr=ipInfo.AddressList;

//得到ip

IPAddress ip=ipAddr[0];

//组合出远程终结点

IPEndPoint hostEP=new IPEndPoint(ip,port);

//创建Socket 实例

Socket socket=new

Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); try {

//尝试连接

socket.Connect(hostEP); }

catch(Exception se) {

MessageBox.Show(\"连接错误\"+se.Message,\"提示信息

,MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); }

//发送给远程主机的请求内容串

string sendStr=\"GET / HTTP/1.1\\r\\nHost: \" + hostName +

\"\\r\\nConnection: Close\\r\\n\\r\\n\";

//创建bytes字节数组以转换发送串

byte[] bytesSendStr=new byte[1024];

//将发送内容字符串转换成字节byte数组

bytesSendStr=Encoding.ASCII.GetBytes(sendStr); try {

//向主机发送请求

socket.Send(bytesSendStr,bytesSendStr.Length,0); }

catch(Exception ce) {

MessageBox.Show(\"发送错误:\"+ce.Message,\"提示信息

,MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); }

//声明接收返回内容的字符串

string recvStr=\"\";

//声明字节数组,一次接收数据的长度为1024字节

byte[] recvBytes=new byte[1024];

//返回实际接收内容的字节数

int bytes=0;

//循环读取,直到接收完所有数据

while(true) {

bytes=socket.Receive(recvBytes,recvBytes.Length,0);

//读取完成后退出循环

if(bytes〈=0)

break;

//将读取的字节数转换为字符串

recvStr+=Encoding.ASCII.GetString(recvBytes,0,bytes); }

//将所读取的字符串转换为字节数组

byte[] content=Encoding.ASCII.GetBytes(recvStr); try {

//创建文件流对象实例

FileStream fs=new

FileStream(fileName,FileMode.OpenOrCreate,FileAccess.ReadWrite);

//写入文件

fs.Write(content,0,content.Length); }

catch(Exception fe) {

MessageBox.Show(\"文件创建/写入错误:\"+fe.Message,\"提示信息\",MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); }

//禁用Socket

socket.Shutdown(SocketShutdown.Both);

//关闭Socket

socket.Close(); }

}

转载自网站:

http://topic.csdn.net/u/20080623/08/4bbd2475-45f1-42e3-a613-16b094759ade.html?85362

因篇幅问题不能全部显示,请点此查看更多更全内容

Top