请教:C#网络编程相关的知识,建立socket服务器时向客户端连接,就建立不了了?
2009-10-21 20:12 杨兴亚 阅读(734) 评论(2) 编辑 收藏 举报我现在在做一个C/S的服务器模型了,用socket(C#)做的,服务器建立的是并发的模型,客户端连接服务器后服务器保存客户端的相关信息,然后启动新线程来处理这个连接了(命令连接),这个连接仅仅发送少量的命令(定义过的格式),当客户端需要服务器的大量的数据文件时,就在客户端新建一个socket并绑定到一个未使用的端口,然后把端口信息通过命令连接传给服务器,服务器受到后就新建一个socket连接客户端的这个侦听端口,但是现在怎么都连不上,不知道问题处在那了?原来的那个命令连接存在了。
建立的模型如下服务器:
Code
public void Start()
{
listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenPort = 7000;
MaxBufferLength = 16 << 10;
listenEndPoint = new IPEndPoint(IPAddress.Any, this.listenPort);
listenSocket.Bind(listenEndPoint);
//get loacl ip;
this.localIp = "192.168.0.100";/*((IPEndPoint) listenSocket.LocalEndPoint).Address.ToString();*/
InitUsefulPortList();
//init client list
this.clientList = new ClientList();
listenSocket.Listen(1000);
while (true)
{
Socket tempsocket = listenSocket.Accept();
ClientId item = new ClientId((IPEndPoint)tempsocket.RemoteEndPoint, tempsocket);
//item.isAuthroize = true;
//item.PdaId = sessionid.ToString();
item.ServerSendConfigSigned = new ManualResetEvent(false);
item.ServerSendConfigSigned2 = new ManualResetEvent(false);
clientList.Add(item);
//this.localIp = ((IPEndPoint)tempsocket.LocalEndPoint).Address.ToString();
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ProcessReceiveData), tempsocket);
}
}
public void Start()
{
listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenPort = 7000;
MaxBufferLength = 16 << 10;
listenEndPoint = new IPEndPoint(IPAddress.Any, this.listenPort);
listenSocket.Bind(listenEndPoint);
//get loacl ip;
this.localIp = "192.168.0.100";/*((IPEndPoint) listenSocket.LocalEndPoint).Address.ToString();*/
InitUsefulPortList();
//init client list
this.clientList = new ClientList();
listenSocket.Listen(1000);
while (true)
{
Socket tempsocket = listenSocket.Accept();
ClientId item = new ClientId((IPEndPoint)tempsocket.RemoteEndPoint, tempsocket);
//item.isAuthroize = true;
//item.PdaId = sessionid.ToString();
item.ServerSendConfigSigned = new ManualResetEvent(false);
item.ServerSendConfigSigned2 = new ManualResetEvent(false);
clientList.Add(item);
//this.localIp = ((IPEndPoint)tempsocket.LocalEndPoint).Address.ToString();
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ProcessReceiveData), tempsocket);
}
}
处理连接的方法:
Code
private void ProcessReceiveData(object serversocket)
{
Socket tempsocket = (Socket)serversocket;
IntPtr sessionid = tempsocket.Handle;
Valid(tempsocket);
//if (!Valid(tempsocket))
//{
// //need transfer login error result;
// string result = "";
// LoginCommand login = new LoginCommand(false, result);
// login.SessionId = sessionid.ToString();
// SendCommand(tempsocket, login);
// return;
//}
ClientId item = clientList.GetClientIdByEndPoint((IPEndPoint)tempsocket.RemoteEndPoint);
item.isAuthroize = true;
item.PdaId = sessionid.ToString();
//need transfer login success
//send login response;
bool isneedupdateconfigfile = true;
LoginCommand log = new LoginCommand(true, "Successful", false, isneedupdateconfigfile);
log.SessionId = sessionid.ToString();
SendCommand(tempsocket, log);
if (isneedupdateconfigfile)
{
item.ServerSendConfigSigned.Set();
item.ServerSendConfigSigned2.WaitOne();
}
ReceiveCommand(tempsocket, item);
}
private void ReceiveCommand(Socket tempsocket,ClientId item)
{
while (tempsocket.Connected)
{
byte[] buffer = new byte[MaxBufferLength];
int count = tempsocket.Receive(buffer);
while (count < 1)
count = tempsocket.Receive(buffer);
byte[] buf = new byte[count];
Buffer.BlockCopy(buffer, 0, buf, 0, count);
ReceiveCommand command = ReceivePacketManager.ReceiveCommand(buf);
//notify high layer;
//有些命令需要创建数据端口。
Socket serverdatasocket = null;
if (IsNeedCreateDataPort(command))
{
serverdatasocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string filename = "";
ReceiveFile(serverdatasocket, filename);
//TODO:
if (ReceiveData != null)
ReceiveData(StaticDefine.TransferType.File, item,filename);
break;
}
//need send data;
if (IsNeedSendData(command))
{
IPEndPoint temp = GetClientDataPort(command);
item.ClientDataIpEndPoint = temp;
serverdatasocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
newConfigfile = @"D:\config.xml";
SendData(temp, serverdatasocket, newConfigfile);
//SendData(temp, tempsocket, newConfigfile);
serverdatasocket.Shutdown(SocketShutdown.Both);
serverdatasocket.Close();
//send data transfer over command
SendCommand(tempsocket, new DataTransferOver());
serverdatasocket.Shutdown(SocketShutdown.Both);
serverdatasocket.Close();
break;
}
//datatransferover command need close socket;
if (IsNeedCloseDataPort(command))
{
CloseDataPort(serverdatasocket);
item.ServerDataIpEndPoint = null;
break;
}
if (IsNeedCreateNetInfoDataPort(command))
{
serverdatasocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ReceiveNetInformation(serverdatasocket,tempsocket,item.PdaId,item);
break;
}
//TODO:
if (ReceiveData != null)
ReceiveData(StaticDefine.TransferType.Command, item, command);
}
}
private void SendData(IPEndPoint clientdataipendpoint,Socket serverdatasocket,string filename)
{
//仅发送配置文件。
FileStream fileStream = null;
IPEndPoint ip = CreateIPEndPoint();
try
{
serverdatasocket.Connect(clientdataipendpoint);
fileStream = File.OpenRead(filename);
byte[] buffer = new byte[MaxBufferLength];
while (0 < fileStream.Read(buffer, 0, MaxBufferLength))
{
serverdatasocket.Send(buffer);
}
System.Diagnostics.Debug.WriteLine("发送配置文件成功");
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("发送配置文件错误:"+ex.Message);
}
if (fileStream != null)
{
fileStream.Close();
fileStream = null;
}
}
private void ProcessReceiveData(object serversocket)
{
Socket tempsocket = (Socket)serversocket;
IntPtr sessionid = tempsocket.Handle;
Valid(tempsocket);
//if (!Valid(tempsocket))
//{
// //need transfer login error result;
// string result = "";
// LoginCommand login = new LoginCommand(false, result);
// login.SessionId = sessionid.ToString();
// SendCommand(tempsocket, login);
// return;
//}
ClientId item = clientList.GetClientIdByEndPoint((IPEndPoint)tempsocket.RemoteEndPoint);
item.isAuthroize = true;
item.PdaId = sessionid.ToString();
//need transfer login success
//send login response;
bool isneedupdateconfigfile = true;
LoginCommand log = new LoginCommand(true, "Successful", false, isneedupdateconfigfile);
log.SessionId = sessionid.ToString();
SendCommand(tempsocket, log);
if (isneedupdateconfigfile)
{
item.ServerSendConfigSigned.Set();
item.ServerSendConfigSigned2.WaitOne();
}
ReceiveCommand(tempsocket, item);
}
private void ReceiveCommand(Socket tempsocket,ClientId item)
{
while (tempsocket.Connected)
{
byte[] buffer = new byte[MaxBufferLength];
int count = tempsocket.Receive(buffer);
while (count < 1)
count = tempsocket.Receive(buffer);
byte[] buf = new byte[count];
Buffer.BlockCopy(buffer, 0, buf, 0, count);
ReceiveCommand command = ReceivePacketManager.ReceiveCommand(buf);
//notify high layer;
//有些命令需要创建数据端口。
Socket serverdatasocket = null;
if (IsNeedCreateDataPort(command))
{
serverdatasocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string filename = "";
ReceiveFile(serverdatasocket, filename);
//TODO:
if (ReceiveData != null)
ReceiveData(StaticDefine.TransferType.File, item,filename);
break;
}
//need send data;
if (IsNeedSendData(command))
{
IPEndPoint temp = GetClientDataPort(command);
item.ClientDataIpEndPoint = temp;
serverdatasocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
newConfigfile = @"D:\config.xml";
SendData(temp, serverdatasocket, newConfigfile);
//SendData(temp, tempsocket, newConfigfile);
serverdatasocket.Shutdown(SocketShutdown.Both);
serverdatasocket.Close();
//send data transfer over command
SendCommand(tempsocket, new DataTransferOver());
serverdatasocket.Shutdown(SocketShutdown.Both);
serverdatasocket.Close();
break;
}
//datatransferover command need close socket;
if (IsNeedCloseDataPort(command))
{
CloseDataPort(serverdatasocket);
item.ServerDataIpEndPoint = null;
break;
}
if (IsNeedCreateNetInfoDataPort(command))
{
serverdatasocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ReceiveNetInformation(serverdatasocket,tempsocket,item.PdaId,item);
break;
}
//TODO:
if (ReceiveData != null)
ReceiveData(StaticDefine.TransferType.Command, item, command);
}
}
private void SendData(IPEndPoint clientdataipendpoint,Socket serverdatasocket,string filename)
{
//仅发送配置文件。
FileStream fileStream = null;
IPEndPoint ip = CreateIPEndPoint();
try
{
serverdatasocket.Connect(clientdataipendpoint);
fileStream = File.OpenRead(filename);
byte[] buffer = new byte[MaxBufferLength];
while (0 < fileStream.Read(buffer, 0, MaxBufferLength))
{
serverdatasocket.Send(buffer);
}
System.Diagnostics.Debug.WriteLine("发送配置文件成功");
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("发送配置文件错误:"+ex.Message);
}
if (fileStream != null)
{
fileStream.Close();
fileStream = null;
}
}
客户端代码:
Code
public void Start()
{
loginErrorCode = null;
isAuthrize = false;
MaxBufferLength = 16 << 10;
localCommandSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//if (!ConnectionManager.Connect(false))
//{
// System.Diagnostics.Debug.WriteLine("无法连接管理器");
// return;
//}
try
{
localCommandSocket.Connect(serverCommandIpEndPoint);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("建立连接失败:"+ex.Message);
//this.localCommandSocket.Shutdown(SocketShutdown.Both);
this.localCommandSocket.Close();
return;
}
this.user = "yangxingya";
this.pass = "yangxingya";
LoginCommand login = new LoginCommand(user, pass);
SendCommand(localCommandSocket, login);
if (!LoginSussess(localCommandSocket))
{
System.Diagnostics.Debug.WriteLine("登陆失败" + loginErrorCode);
return;
}
System.Diagnostics.Debug.WriteLine("登陆成功");
commandReceiveThread = new Thread(new ThreadStart(Receivecommand));
commandReceiveThread.Start();
}
private void Receivecommand()
{
Receivecommand(localCommandSocket);
}
private bool LoginSussess(Socket localCommandSocket)
{
bool temp = false;
byte[] buffer = new byte[MaxBufferLength];
int count = 0;
while (count < 1 && localCommandSocket.Connected)
{
count = localCommandSocket.Receive(buffer);
}
byte[] buf = new byte[count];
Buffer.BlockCopy(buffer, 0, buf, 0, count);
ReceiveCommand command = ReceivePacketManager.ReceiveCommand(buf);
LoginResponseCommand login = command as LoginResponseCommand;
if (login != null)
{
if (login.IsLogin)
{
temp = true;
loginErrorCode = login.Code;
}
this.sessionId = login.SessionId;
if (IsNeedCreateReceiveDataPort(command))
{
this.clientDataIpEndPoint = new IPEndPoint(IPAddress.Any, 30000);
//this.dataReceiveThread = new Thread(new ThreadStart(ReceiveData));
//this.dataReceiveThread.Start();
ReceiveData();
}
}
System.Diagnostics.Debug.WriteLine("登陆"+(temp?"成功":"失败"));
return temp;
}
private void Receivecommand(Socket localCommandSocket)
{
//throw new NotImplementedException();
while (localCommandSocket.Connected)
{
byte[] buffer = new byte[MaxBufferLength];
int count;
do
{
count = localCommandSocket.Receive(buffer);
} while (count < 1);
ReceiveCommand command = ReceivePacketManager.ReceiveCommand(buffer);
if (IsNeedSendFile(command))
{
UploadDataRequestCommand uploadfile=command as UploadDataRequestCommand;
if(uploadfile!=null)
{
IPHostEntry iphost=Dns.Resolve(uploadfile.Ip);
IPAddress ipaddress=iphost.AddressList[0];
this.serverDataIpEndPoint=new IPEndPoint (ipaddress,uploadfile.Port);
Socket temp=new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
string filename="";
temp.Connect(this.serverDataIpEndPoint);
SendFile(temp,filename);
SendCommand(localCommandSocket, new SendDataPacket.DataTransferOverCommand());
}
}
if (IsNeedSendNetInfo(command))
{
UploadResponseCommand uploadnetinfo = command as UploadResponseCommand;
if (uploadnetinfo != null)
{
IPHostEntry iphost = Dns.Resolve(uploadnetinfo.Ip);
IPAddress ipaddress = iphost.AddressList[0];
this.serverDataIpEndPoint = new IPEndPoint(ipaddress, uploadnetinfo.Port);
if (SendNetInfo(this.serverDataIpEndPoint, netInfo))
{
SendCommand(localCommandSocket, new SendDataPacket.DataTransferOverCommand());
netInfo = null;
}
}
}
if (IsNeedCloseDataPort(command))
{
if (this.configFileStream != null)
{
this.configFileStream.Close();
this.configFileStream = null;
}
if (localDataSocket != null)
{
localDataSocket.Shutdown(SocketShutdown.Both);
localDataSocket.Close();
localDataSocket = null;
}
}
}
}
private void ReceiveData()
{
Socket temp = null;
try
{
localDataSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint end = new IPEndPoint(IPAddress.Any, clientDataIpEndPoint.Port);
localDataSocket.Bind(end);
localDataSocket.Listen(1000);
//发送命令
ConfigUpdateStartCommand configupdatestart = new ConfigUpdateStartCommand(((IPEndPoint)localCommandSocket.LocalEndPoint).Address.ToString(), clientDataIpEndPoint.Port);
SendCommand(localCommandSocket, configupdatestart);
temp = localDataSocket.Accept();
byte[] buffer = new byte[MaxBufferLength];
string configFileName = @"\config.xml";
this.configFileStream = File.Create(configFileName);
int count = temp.Receive(buffer);
while (count < 1)
{
count = temp.Receive(buffer);
}
while (count >0)
{
configFileStream.Write(buffer, 0, count);
count = temp.Receive(buffer);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("接受配置文件错误:"+ex.Message);
//if (this.localDataSocket != null)
//{
// this.localDataSocket.Shutdown(SocketShutdown.Both);
// this.localDataSocket.Close();
//}
}
if (temp != null)
{
temp.Shutdown(SocketShutdown.Both);
temp.Close();
temp = null;
}
if (this.configFileStream != null)
{
this.configFileStream.Close();
this.configFileStream = null;
}
}
public void Start()
{
loginErrorCode = null;
isAuthrize = false;
MaxBufferLength = 16 << 10;
localCommandSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//if (!ConnectionManager.Connect(false))
//{
// System.Diagnostics.Debug.WriteLine("无法连接管理器");
// return;
//}
try
{
localCommandSocket.Connect(serverCommandIpEndPoint);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("建立连接失败:"+ex.Message);
//this.localCommandSocket.Shutdown(SocketShutdown.Both);
this.localCommandSocket.Close();
return;
}
this.user = "yangxingya";
this.pass = "yangxingya";
LoginCommand login = new LoginCommand(user, pass);
SendCommand(localCommandSocket, login);
if (!LoginSussess(localCommandSocket))
{
System.Diagnostics.Debug.WriteLine("登陆失败" + loginErrorCode);
return;
}
System.Diagnostics.Debug.WriteLine("登陆成功");
commandReceiveThread = new Thread(new ThreadStart(Receivecommand));
commandReceiveThread.Start();
}
private void Receivecommand()
{
Receivecommand(localCommandSocket);
}
private bool LoginSussess(Socket localCommandSocket)
{
bool temp = false;
byte[] buffer = new byte[MaxBufferLength];
int count = 0;
while (count < 1 && localCommandSocket.Connected)
{
count = localCommandSocket.Receive(buffer);
}
byte[] buf = new byte[count];
Buffer.BlockCopy(buffer, 0, buf, 0, count);
ReceiveCommand command = ReceivePacketManager.ReceiveCommand(buf);
LoginResponseCommand login = command as LoginResponseCommand;
if (login != null)
{
if (login.IsLogin)
{
temp = true;
loginErrorCode = login.Code;
}
this.sessionId = login.SessionId;
if (IsNeedCreateReceiveDataPort(command))
{
this.clientDataIpEndPoint = new IPEndPoint(IPAddress.Any, 30000);
//this.dataReceiveThread = new Thread(new ThreadStart(ReceiveData));
//this.dataReceiveThread.Start();
ReceiveData();
}
}
System.Diagnostics.Debug.WriteLine("登陆"+(temp?"成功":"失败"));
return temp;
}
private void Receivecommand(Socket localCommandSocket)
{
//throw new NotImplementedException();
while (localCommandSocket.Connected)
{
byte[] buffer = new byte[MaxBufferLength];
int count;
do
{
count = localCommandSocket.Receive(buffer);
} while (count < 1);
ReceiveCommand command = ReceivePacketManager.ReceiveCommand(buffer);
if (IsNeedSendFile(command))
{
UploadDataRequestCommand uploadfile=command as UploadDataRequestCommand;
if(uploadfile!=null)
{
IPHostEntry iphost=Dns.Resolve(uploadfile.Ip);
IPAddress ipaddress=iphost.AddressList[0];
this.serverDataIpEndPoint=new IPEndPoint (ipaddress,uploadfile.Port);
Socket temp=new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
string filename="";
temp.Connect(this.serverDataIpEndPoint);
SendFile(temp,filename);
SendCommand(localCommandSocket, new SendDataPacket.DataTransferOverCommand());
}
}
if (IsNeedSendNetInfo(command))
{
UploadResponseCommand uploadnetinfo = command as UploadResponseCommand;
if (uploadnetinfo != null)
{
IPHostEntry iphost = Dns.Resolve(uploadnetinfo.Ip);
IPAddress ipaddress = iphost.AddressList[0];
this.serverDataIpEndPoint = new IPEndPoint(ipaddress, uploadnetinfo.Port);
if (SendNetInfo(this.serverDataIpEndPoint, netInfo))
{
SendCommand(localCommandSocket, new SendDataPacket.DataTransferOverCommand());
netInfo = null;
}
}
}
if (IsNeedCloseDataPort(command))
{
if (this.configFileStream != null)
{
this.configFileStream.Close();
this.configFileStream = null;
}
if (localDataSocket != null)
{
localDataSocket.Shutdown(SocketShutdown.Both);
localDataSocket.Close();
localDataSocket = null;
}
}
}
}
private void ReceiveData()
{
Socket temp = null;
try
{
localDataSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint end = new IPEndPoint(IPAddress.Any, clientDataIpEndPoint.Port);
localDataSocket.Bind(end);
localDataSocket.Listen(1000);
//发送命令
ConfigUpdateStartCommand configupdatestart = new ConfigUpdateStartCommand(((IPEndPoint)localCommandSocket.LocalEndPoint).Address.ToString(), clientDataIpEndPoint.Port);
SendCommand(localCommandSocket, configupdatestart);
temp = localDataSocket.Accept();
byte[] buffer = new byte[MaxBufferLength];
string configFileName = @"\config.xml";
this.configFileStream = File.Create(configFileName);
int count = temp.Receive(buffer);
while (count < 1)
{
count = temp.Receive(buffer);
}
while (count >0)
{
configFileStream.Write(buffer, 0, count);
count = temp.Receive(buffer);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("接受配置文件错误:"+ex.Message);
//if (this.localDataSocket != null)
//{
// this.localDataSocket.Shutdown(SocketShutdown.Both);
// this.localDataSocket.Close();
//}
}
if (temp != null)
{
temp.Shutdown(SocketShutdown.Both);
temp.Close();
temp = null;
}
if (this.configFileStream != null)
{
this.configFileStream.Close();
this.configFileStream = null;
}
}
请高手给指点一下问题处在那里了?