Socket类代码:
namespace bnSocket
{
class bnSocket
{
private Socket m_socket;
private int m_nReturn;
public bnSocket()
{
}
/// <summary>
/// 发送数据到服务器
/// </summary>
/// <param name="sSend">发送内容</param>
/// <returns>返回异常消息</returns>
public string SendData(string sSend)
{
string msg = "";
try
{
if (m_nReturn != -1)
{
msg = "ABC网络异常,无法请求服务器!"; //是否已经连接到服务器
}
byte[] byteMesage = new byte[sSend.Length];
byteMesage = Encoding.GetEncoding("gb2312").GetBytes(sSend);// .Default.GetBytes(sSend);
m_socket.Send(byteMesage);
}
catch
{
msg = "ABC网络异常断开连接";
}
return msg;
}
/// <summary>
/// 从服务器获取信息
/// </summary>
/// <returns>服务器返回信息给客户端</returns>
public string ReceiveMsg()
{
string msg = "";
try
{
if (m_nReturn != -1)
{
msg = "ABC网络异常,无法请求服务器!"; //是否已经连接到服务器
}
while (true)
{
byte[] byRead = new byte[1024];
m_socket.Receive(byRead);
msg = Encoding.GetEncoding("gb2312").GetString(byRead, 0, byRead.Length);
Thread.Sleep(500);
if (byRead.Length == 0)
{
break;
}
}
}
catch(Exception ex)
{
msg = "ABC网络异常断开连接";
}
return msg;
}
/// <summary>
/// 连接服务器
/// </summary>
/// <param name="sServerIp">服务器IP地址</param>
/// <param name="nPort">端口号</param>
/// <returns>-1=>成功; -2=>IP无效; -3=>连接服务器失败,请查看服务器是否已经运行或者网络连接是否正常</returns>
public int ConnectServer(string sServerIp, int nPort)
{
IPAddress serverIp;
try
{
serverIp = IPAddress.Parse(sServerIp);
}
catch
{
//连接失败,IP无效
m_nReturn = -2;
return -2;
}
try
{
IPEndPoint iep = new IPEndPoint(serverIp, nPort);
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_socket.Connect(iep);
m_nReturn = -1;
return -1; //连接成功
}
catch
{
//连接服务器失败,请查看服务器是否已经运行或者网络连接是否正常
m_nReturn = -3;
return -3;
}
}
/// <summary>
/// 获取本机IP地址
/// </summary>
public string GetIPAddress()
{
IPHostEntry ipAddress = Dns.GetHostByName(Dns.GetHostName());
return ipAddress.AddressList[0].ToString();
}
/// <summary>
/// 断开与服务器的连接
/// </summary>
public int EndConnectServer()
{
if (m_nReturn == -1)
{
m_socket.Shutdown(SocketShutdown.Both);
m_socket.Close();
m_nReturn = -100;
}
return m_nReturn;
}
/// <summary>
/// 获得连接状态
/// </summary>
/// <returns></returns>
public int GetConnectState()
{
return m_nReturn;
}
}
}
4 个解决方案
#1
客户端窗体部分代码:
namespace PDA
{
public partial class frm_Main : Form
{
public frm_Main()
{
InitializeComponent();
}
//定义启动网络连接的定时器
System.Threading.Timer startNetTimer;
//定义定时器
System.Threading.Timer timer;
System.Threading.Timer getSNTimer;
System.Threading.Timer getNetStatus;
System.Threading.Timer receiveMsgTimer;
Thread receiveMsg;
//服务器连接状态标志
private int m_ConnectionState = 0;
private bnSocket.bnSocket mySocket = new bnSocket.bnSocket();
//(2) 全局变量
//(2.1) 记录上次操作模块
private string m_sLastModule = "";
//(2.2) 主程序全路径 + 名称
private static string m_sFullAppName = Assembly.GetExecutingAssembly().GetName().CodeBase;
//(2.3) 主程序全路径
private static string m_sFullAppPath = Path.GetDirectoryName(m_sFullAppName); //PAD
//(2.3) 基础数据库文件连接对像
private string m_TempSaveFile = m_sFullAppPath + @"\_Save.txt";
//(2.8) 网络连接IP地址
private string m_sIP = "";
//(2.9) 网络连接端口号
private int m_nPort = 0;
#region 初始
private void frm_Main_Load(object sender, EventArgs e)
{
//设置窗体位于程序最顶端
this.TopMost = true;
string sLines = "";
string[] strArr;
string filename = m_sFullAppPath + @"\config.ini";
StreamReader sr = new StreamReader(filename, Encoding.Default);
while ((sLines = sr.ReadLine()) != null)
{
strArr = sLines.Split('|');
m_sIP = strArr[0].ToString().Trim();
m_nPort = Convert.ToInt32(strArr[1].ToString().Trim());
}
sr.Close();
//读取原密码
string pwdFileName = m_sFullAppPath + @"\gzbonny.bin";
if (File.Exists(pwdFileName))
{
string sPwd = Commond.ReadFile(pwdFileName);
m_sOldPwd = Commond.DecryptString(sPwd);
}
this.lblStatus.Text = "正在连接网络...";
//启用定时器执行服务器连接
object obj = (object)7;
startNetTimer = new System.Threading.Timer(new TimerCallback(Connect2Server), obj, 1000, 2000);
}
/// <summary>
/// 连接服务器
/// </summary>
private void Connect2Server(object obj)
{
if (startNetTimer != null)
{
startNetTimer.Dispose();
startNetTimer = null;
}
m_ConnectionState = mySocket.ConnectServer(m_sIP, m_nPort);
this.Invoke(new EventHandler(delegate
{
switch (m_ConnectionState)
{
case -1:
this.lblStatus.Text = "已连接";
this.lblStatus2.Text = "已连接";
string ipAddress = mySocket.GetIPAddress();
//向服务端发送信息
string msg = "The client " + ipAddress + " online!";
mySocket.SendData(msg);
//开启定时器,启用接收数据的线程
receiveMsgTimer = new System.Threading.Timer(new TimerCallback(StartThread), obj, 1000, 1000);
break;
case -2:
this.lblStatus.Text = "IP无效";
this.lblStatus2.Text = "IP无效";
break;
case -3:
this.lblStatus.Text = "网络异常连接失败";
this.lblStatus2.Text = "网络异常连接失败";
break;
case -100:
this.lblStatus.Text = "网络异常断开连接";
this.lblStatus2.Text = "网络异常断开连接";
break;
default:
this.lblStatus.Text = "网络异常,请查看无线网络";
this.lblStatus2.Text = "网络异常,请查看无线网络";
break;
}
}));
this.BeginTheTimer();
}
//启动定时器
private void BeginTheTimer()
{
//这里只是要一个object类型数据,用它做为下面Timer的参数之一,没有其它意思
object myobject = (object)7;
//暂时设定为2秒钟启动一次!
timer = new System.Threading.Timer(new System.Threading.TimerCallback(GetState), myobject, 3000, 5000);
}
/// <summary>
/// 获取连接状态
/// </summary>
private void GetState(object myobject)
{
string msg = mySocket.SendData("C2S");
if (msg.StartsWith("ABC网络异常"))
{
timer.Dispose();
m_ConnectionState = -3;
object obj = (object)7;
this.Connect2Server(obj);
}
}
#endregion
/// <summary>
/// 执行线程
/// </summary>
/// <param name="obj"></param>
private void StartThread(object obj)
{
if (receiveMsgTimer != null)
{
receiveMsgTimer.Dispose();
receiveMsgTimer = null;
}
//开启线程,执行GetMsg()接收服务端消息
receiveMsg = new Thread(new ThreadStart(GetMsg));
receiveMsg.IsBackground = true;
receiveMsg.Start();
}
#region 发送
private void Send()
{
if (!ValiText())
return;
string InitMsg = this.txtReceive.Text;
string sendMsg = m_operateParam + InitMsg + ":" + this.txtSendMsg.Text;
string returnMsg = mySocket.SendData(sendMsg);
if (returnMsg != "")
{
this.txtReceive.Text = returnMsg.Substring(3);
}
//this.txtReceive.Text = returnMsg;
this.txtSendMsg.Text = "";
this.txtSendMsg.Focus();
}
#endregion
#region 接收信息
private void GetMsg()
{
this.Invoke(new EventHandler(delegate {
this.txtReceive.Text = mySocket.ReceiveMsg();
}));
}
#endregion
}
}
#2
和环境相关,在模拟器上调试Socket时也是只能单方向的
#3
与环境相关的话问题是不是很不好解决?
#4
Thread.Sleep(500);
if (byRead.Length == 0)
{
break;
}
会不会是sleep 500ms,一直有数据,就在循环里出不来了?
if (byRead.Length == 0)
{
break;
}
会不会是sleep 500ms,一直有数据,就在循环里出不来了?
#1
客户端窗体部分代码:
namespace PDA
{
public partial class frm_Main : Form
{
public frm_Main()
{
InitializeComponent();
}
//定义启动网络连接的定时器
System.Threading.Timer startNetTimer;
//定义定时器
System.Threading.Timer timer;
System.Threading.Timer getSNTimer;
System.Threading.Timer getNetStatus;
System.Threading.Timer receiveMsgTimer;
Thread receiveMsg;
//服务器连接状态标志
private int m_ConnectionState = 0;
private bnSocket.bnSocket mySocket = new bnSocket.bnSocket();
//(2) 全局变量
//(2.1) 记录上次操作模块
private string m_sLastModule = "";
//(2.2) 主程序全路径 + 名称
private static string m_sFullAppName = Assembly.GetExecutingAssembly().GetName().CodeBase;
//(2.3) 主程序全路径
private static string m_sFullAppPath = Path.GetDirectoryName(m_sFullAppName); //PAD
//(2.3) 基础数据库文件连接对像
private string m_TempSaveFile = m_sFullAppPath + @"\_Save.txt";
//(2.8) 网络连接IP地址
private string m_sIP = "";
//(2.9) 网络连接端口号
private int m_nPort = 0;
#region 初始
private void frm_Main_Load(object sender, EventArgs e)
{
//设置窗体位于程序最顶端
this.TopMost = true;
string sLines = "";
string[] strArr;
string filename = m_sFullAppPath + @"\config.ini";
StreamReader sr = new StreamReader(filename, Encoding.Default);
while ((sLines = sr.ReadLine()) != null)
{
strArr = sLines.Split('|');
m_sIP = strArr[0].ToString().Trim();
m_nPort = Convert.ToInt32(strArr[1].ToString().Trim());
}
sr.Close();
//读取原密码
string pwdFileName = m_sFullAppPath + @"\gzbonny.bin";
if (File.Exists(pwdFileName))
{
string sPwd = Commond.ReadFile(pwdFileName);
m_sOldPwd = Commond.DecryptString(sPwd);
}
this.lblStatus.Text = "正在连接网络...";
//启用定时器执行服务器连接
object obj = (object)7;
startNetTimer = new System.Threading.Timer(new TimerCallback(Connect2Server), obj, 1000, 2000);
}
/// <summary>
/// 连接服务器
/// </summary>
private void Connect2Server(object obj)
{
if (startNetTimer != null)
{
startNetTimer.Dispose();
startNetTimer = null;
}
m_ConnectionState = mySocket.ConnectServer(m_sIP, m_nPort);
this.Invoke(new EventHandler(delegate
{
switch (m_ConnectionState)
{
case -1:
this.lblStatus.Text = "已连接";
this.lblStatus2.Text = "已连接";
string ipAddress = mySocket.GetIPAddress();
//向服务端发送信息
string msg = "The client " + ipAddress + " online!";
mySocket.SendData(msg);
//开启定时器,启用接收数据的线程
receiveMsgTimer = new System.Threading.Timer(new TimerCallback(StartThread), obj, 1000, 1000);
break;
case -2:
this.lblStatus.Text = "IP无效";
this.lblStatus2.Text = "IP无效";
break;
case -3:
this.lblStatus.Text = "网络异常连接失败";
this.lblStatus2.Text = "网络异常连接失败";
break;
case -100:
this.lblStatus.Text = "网络异常断开连接";
this.lblStatus2.Text = "网络异常断开连接";
break;
default:
this.lblStatus.Text = "网络异常,请查看无线网络";
this.lblStatus2.Text = "网络异常,请查看无线网络";
break;
}
}));
this.BeginTheTimer();
}
//启动定时器
private void BeginTheTimer()
{
//这里只是要一个object类型数据,用它做为下面Timer的参数之一,没有其它意思
object myobject = (object)7;
//暂时设定为2秒钟启动一次!
timer = new System.Threading.Timer(new System.Threading.TimerCallback(GetState), myobject, 3000, 5000);
}
/// <summary>
/// 获取连接状态
/// </summary>
private void GetState(object myobject)
{
string msg = mySocket.SendData("C2S");
if (msg.StartsWith("ABC网络异常"))
{
timer.Dispose();
m_ConnectionState = -3;
object obj = (object)7;
this.Connect2Server(obj);
}
}
#endregion
/// <summary>
/// 执行线程
/// </summary>
/// <param name="obj"></param>
private void StartThread(object obj)
{
if (receiveMsgTimer != null)
{
receiveMsgTimer.Dispose();
receiveMsgTimer = null;
}
//开启线程,执行GetMsg()接收服务端消息
receiveMsg = new Thread(new ThreadStart(GetMsg));
receiveMsg.IsBackground = true;
receiveMsg.Start();
}
#region 发送
private void Send()
{
if (!ValiText())
return;
string InitMsg = this.txtReceive.Text;
string sendMsg = m_operateParam + InitMsg + ":" + this.txtSendMsg.Text;
string returnMsg = mySocket.SendData(sendMsg);
if (returnMsg != "")
{
this.txtReceive.Text = returnMsg.Substring(3);
}
//this.txtReceive.Text = returnMsg;
this.txtSendMsg.Text = "";
this.txtSendMsg.Focus();
}
#endregion
#region 接收信息
private void GetMsg()
{
this.Invoke(new EventHandler(delegate {
this.txtReceive.Text = mySocket.ReceiveMsg();
}));
}
#endregion
}
}
#2
和环境相关,在模拟器上调试Socket时也是只能单方向的
#3
与环境相关的话问题是不是很不好解决?
#4
Thread.Sleep(500);
if (byRead.Length == 0)
{
break;
}
会不会是sleep 500ms,一直有数据,就在循环里出不来了?
if (byRead.Length == 0)
{
break;
}
会不会是sleep 500ms,一直有数据,就在循环里出不来了?