问题
I have a windows service act as a server. And I run one windows form application form localhost as a client. Both the programs use TCP socket connection to send/recieve data. Server listens on port 8030. The program works fine.
BUt when I enhanced the client program to communicate on specific port let's say 9030. While getting connected to server it generates the following exception.
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 192.168.10.198:8030
Any suggestion will be highly appreciated.
Thanks, Madhusmita
For refrence
Server Program Code
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();
}
}
Client Program Code
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.");
}
}
}
回答1:
Note: You don't have to bind the local end of the client's socket -- the framework and/or OS will bind to an ephemeral port automatically. In fact, if you bind the socket to 127.0.0.1, assuming connecting doesn't throw an exception about unreachable hosts, one of two things will happen (i'm not sure which):
- The client will try and connect to the server, but since the local end is bound to the loopback interface's IP, it will send over that instead of over the network. -or-
- The client will correctly route the packet out through the NIC, and the server gets it. The server replies "OK, let's get this connection set up" to the client...but since the client said its address was 127.0.0.1, that's where the server will be trying to connect. Using its own loopback interface, cause that's where 127.0.0.1 is routed to.
Either way, the packets get lost in one of the machines' loopback interfaces, and the client will never see a response.
If you must bind in the client, pick your real IP address, or use IPAddress.Any
, like so:
var endPoint = new IPEndPoint(IPAddress.Any, 9030);
That'll bind to a given port but still let the OS choose the IP address. But 127.0.0.1 probably won't work.
来源:https://stackoverflow.com/questions/7834780/c-sharp-tcp-socket-error-10060