我有一个Windows服务充当服务器。我运行一个Windows窗体申请表localhost作为客户端。两个程序都使用TCP套接字连接来发送/接收数据。 服务器侦听端口8030.程序运行正常。
当我增强客户端程序以在特定端口上进行通信时,请说9030.在连接到服务器时,它会生成以下异常。
连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机无法响应192.168.10.198:8030
任何建议都将受到高度赞赏。
谢谢, Madhusmita
参考
服务器程序代码
public partial class TestService : ServiceBase
{
Socket serverSocket = null;
public Timer timer1;
IPEndPoint ipEndPoint;
public TestService()
{
InitializeComponent();
timer1 = new Timer(10000);
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
}
protected override void OnStart(string[] args)
{
EventLog.WriteEntry("Application", "Service started", EventLogEntryType.Information, 555);
try
{
ipEndPoint = new IPEndPoint(IPAddress.Any, 8030);
//Defines the kind of socket we want :TCP
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
//Bind the socket to the local end point(associate the socket to local end point)
serverSocket.Bind(ipEndPoint);
//listen for incoming connection attempt
// Start listening, only allow 10 connection to queue at the same time
serverSocket.Listen(10);
timer1.Start();
}
catch (SocketException ex)
{
EventLog.WriteEntry("Application", ex.ErrorCode + "-" +ex.Message, EventLogEntryType.Error, 555);
}
catch (Exception ex)
{
EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);
}
}
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
// The program is suspended while waiting for an incoming connection.
// This is a synchronous TCP application
Socket handler = serverSocket.Accept();
byte[] fileDetails = new byte[1500];
//Recieve the file details
handler.Receive(fileDetails);
int fileNameLength = BitConverter.ToInt32(fileDetails, 0);
string fileName = Encoding.ASCII.GetString(fileDetails, 4, fileNameLength);
int fileLength = BitConverter.ToInt32(fileDetails, 4 + fileNameLength);
FileStream fs = new FileStream(@"C:\Demo\" + fileName, FileMode.Append, FileAccess.Write);
int byteRead = 0;
while (byteRead < fileLength)
{
byte[] data = new Byte[1500];
//Recieve teh data and write to the file
int r = handler.Receive(data);
fs.Write(data, 0, r);
byteRead += r;
}
fs.Close();
EventLog.WriteEntry("Application", "File saved successfully", EventLogEntryType.SuccessAudit, 555);
EndPoint endPoint = (EndPoint)ipEndPoint;
handler.Send(Encoding.ASCII.GetBytes("Done"));
handler.Close();
}
catch (SocketException ex)
{
EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);
}
catch (IOException ex)
{
EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);
}
catch (Exception ex)
{
EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);
}
}
protected override void OnStop()
{
timer1.Stop();
}
protected override void OnPause()
{
timer1.Stop();
}
protected override void OnContinue()
{
timer1.Start();
}
protected override void OnShutdown()
{
timer1.Stop();
}
}
客户端程序代码
public partial class Form1 : Form
{
Socket socketClient;
IPEndPoint remoteEndPoint;
public Form1()
{
InitializeComponent();
}
private void buttonX1_Click(object sender, EventArgs e)
{
try
{
//Code to connect to server by by specifing the IP and port of the server on
//which the server application is hosted
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//socketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress,(int)1);
//IP address of the machine where the server program is hosted
IPAddress remoteIPAddress = IPAddress.Parse(txtXIPAddress.Text.Trim());
//Specify the specific port no thart the server listens to accept the data
int port = int.Parse(txtXPort.Text.Trim());
remoteEndPoint = new IPEndPoint(remoteIPAddress, port);
**//This two line causing the exception**
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9030);
socketClient.Bind(endPoint);
//Establish the connection to server
socketClient.Connect(remoteEndPoint);
MessageBox.Show("Connection established. Please select a file to send.");
}
catch (SocketException ex)
{
MessageBox.Show(ex.ErrorCode.ToString() + "-" + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnXBrowse_Click(object sender, EventArgs e)
{
if (socketClient != null)
{
openFileDialog1.ShowDialog();
}
else
{
MessageBox.Show("Please connect to the server first");
}
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
txtXFile.Text = openFileDialog1.FileName;
}
private void btnXTransfer_Click(object sender, EventArgs e)
{
//Check if the socket is connected to the remote host
//otherwise prompt user to get connected to the server first
if (socketClient != null && socketClient.Connected)
{
//If any file is selected then only proceed with transfer
if (!openFileDialog1.FileName.Equals(string.Empty))
{
FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
try
{
//Get the filename
string filename = Path.GetFileName(openFileDialog1.FileName);
//Covert the file name in form of byte
byte[] fileNameByte = Encoding.ASCII.GetBytes(filename);
//4- to store the filename length(as int - 4bytes)
//8- to stote the file content length(as long take 8 bytes)
int totalLength = 4 + fileNameByte.Length + 8;
//Clientdata[] reprents the data to sent to the server
//which represent the file details
byte[] clientData = new byte[totalLength];
byte[] fileNameLength = BitConverter.GetBytes(fileNameByte.Length);
byte[] fileContentLength = BitConverter.GetBytes(fs.Length);
//Copy all the data ClientData array
fileNameLength.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileContentLength.CopyTo(clientData, 4 + fileNameByte.Length);
//Send the data to server
socketClient.Send(clientData);
int byteRead = 0;
int bytesToRead = (int)fs.Length;
while (bytesToRead > 0)
{
byte[] data = new Byte[1500];
byteRead = bytesToRead > 1500 ? 1500 : bytesToRead;
int n = fs.Read(data, 0, byteRead);
//Send the data to server
socketClient.Send(data);
bytesToRead -= n;
}
//Code block to get the success message from server
byte[] successmessage = new byte[4];
int msg = socketClient.Receive(successmessage);
if (Encoding.ASCII.GetString(successmessage).Equals("Done"))
{
MessageBox.Show("transfered the file successfully");
txtXFile.Text = string.Empty;
openFileDialog1.FileName = string.Empty;
}
}
catch (SocketException ex)
{
MessageBox.Show(ex.ErrorCode + "-" + ex.Message);
}
catch (IOException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
fs.Close();
if (socketClient != null && socketClient.Connected)
{
socketClient.Shutdown(SocketShutdown.Both);
socketClient.Close(); ;
}
}
}
else
{
MessageBox.Show("Please select afile to transfer.");
}
}
else
{
MessageBox.Show("Please connect to the host.");
}
}
}
答案 0 :(得分:2)
注意:您不必绑定客户端套接字的本地端 - 框架和/或操作系统将自动绑定到临时端口。实际上,如果将套接字绑定到127.0.0.1,假设连接不会抛出关于无法访问的主机的异常,则会发生以下两种情况之一(我不确定是哪种情况):
无论哪种方式,数据包都会在其中一台机器的环回接口中丢失,客户端永远不会看到响应。
如果您必须在客户端绑定,请选择您的真实IP地址,或使用IPAddress.Any
,如下所示:
var endPoint = new IPEndPoint(IPAddress.Any, 9030);
这将绑定到给定端口,但仍然让操作系统选择IP地址。但是127.0.0.1可能无法正常工作。