我想创建一个客户端和服务器程序,以在彼此之间发送对象并使它工作,以便两个程序可以在两个独立的主机系统上进行通信。
在同一主机系统上运行这两个程序可以使其正常工作,但是当我尝试在两个不同的系统上运行服务器程序和客户端程序时,我只是在客户端收到超时错误。在一种奇怪的情况下,通过在我的PC上运行服务器,在我的工作笔记本电脑上运行客户端,它实际上可以工作。但是,当尝试使用另一台笔记本电脑连接到服务器时,它不起作用。当我在笔记本电脑上拥有服务器,在PC上拥有客户端时,它也将无法工作。
服务器代码:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace Controller
{
//Class for handeling induvidual clients seperatly
class ClientHandler
{
static LinkedList<ClientHandler> allClients = new LinkedList<ClientHandler>(); //List of client handlers
static int nextNo = 0;
//lock used on client handler list when adding a new client handler
private readonly object synLock = new object();
TcpClient MyClient;
string MyName;
NetworkStream MyStream;
public ClientHandler(TcpClient clientInfo)
{
Console.WriteLine("ClientHandler created");
//client object for the handler
this.MyClient = clientInfo;
//Name of the clienthandler (to differentiate them from eachother)
this.MyName = "Client" + nextNo.ToString();
//Gets the stream for the client
this.MyStream = MyClient.GetStream();
//Make sure that only one thread can add clienthandler to list at a time
lock (synLock)
{
allClients.AddLast(this);
nextNo++;
}
Thread clientthread = new Thread(listenandsend);
clientthread.Start();
}
//Thread for reading what clients sends over stream
public void listenandsend()
{
while (true)
{ //Buffer for recieving data
byte[] recievedBuffer = new byte[1000];
//Places data it gets from the client into the buffer
MyStream.Read(recievedBuffer, 0, recievedBuffer.Length);
//transform byte array to object of contest class (ref divingClassLibrary)
divingClassLibrary.Contest c = divingClassLibrary.Contest.fromByte(recievedBuffer);
//Test to see if it got the right object
Console.WriteLine("CONTEST NAME: " + c.name + ", CONTEST DATE: " + c.date);
}
}
}
class ControllerProgram
{
static void Main(string[] args)
{
//------- --This section is used for printing out the servers own ip address---------
string serverIP = "";
IPAddress[] localIP = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress address in localIP)
{
if (address.AddressFamily == AddressFamily.InterNetwork)
{
serverIP = address.ToString();
}
}
Console.WriteLine(serverIP);
//--------------------------------------------------------------------------------
//Creates a listner for the server
TcpListener serverListner = new TcpListener(IPAddress.Parse(serverIP), 8080);
TcpClient client = default(TcpClient);
//----------------trys-catch for starting listener-----------------
try
{
serverListner.Start();
Console.WriteLine("Server started...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.Read();
}
//-----------------------------------------------------
//----------------Loop for listening for clients-------------------
while (true)
{
client = serverListner.AcceptTcpClient();
Console.WriteLine("Found a clients");
ClientHandler handle = new ClientHandler(client);
}
//----------------------------------------------------------------
}
}
}
客户代码:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace ClientProgram
{
class client
{
static TcpClient serverclient;
static NetworkStream MyStream;
static void Main(string[] args)
{
//Asks the user for the ip address of the server
Console.WriteLine("Type in the ip address of server:");
//Puts the ip address to a string
string serverIP = Console.ReadLine();
int port = 8080;
serverclient = new TcpClient();
//Creates the endpoint for the client
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(serverIP), port);
//--------------Try-catch for connectng to server------------------
try
{
serverclient.Connect(ipEnd);
}
catch(Exception ex) {
Console.WriteLine(ex.ToString());
Console.Read();
}
//-----------------------------------------------------------------
if (serverclient.Connected)
{
Console.WriteLine("I got connected!");
MyStream = serverclient.GetStream();
//Starts the thread for listening to the server
Thread listnerThread = new Thread(listentoserver);
listnerThread.Start();
while (true)
{
//Asks he user for the contest name
Console.WriteLine("Enter Contest name: ");
string name = Console.ReadLine();
//Asks he user for the contest date
Console.WriteLine("Enter Contest date: ");
string date = Console.ReadLine();
//Creates an byte array by creating the contest object and converting it into bytes
byte[] sendData = divingClassLibrary.Contest.toByte(new divingClassLibrary.Contest(0, name, date));
//Sends the byte array to the server
MyStream.Write(sendData, 0, sendData.Length);
//for ending the connection and the program (will be used later)
if (sendData.Equals("bye"))
{
break;
}
}
MyStream.Close();
serverclient.Close();
}
}
}
}
客户应连接并开始要求用户输入比赛的名称,然后输入比赛的日期,但我只会收到超时错误。
答案 0 :(得分:-1)
我认为问题出在您的服务器代码中。 这行:
TcpListener serverListner = new TcpListener(IPAddress.Parse(serverIP), 8080);
基本上说侦听器正在等待8080,但是,您的服务器不在该端口中,我认为这就是为什么当您在同一主机上同时拥有两个代码(服务器和客户端)时的原因。
注意:如果您使用其他笔记本电脑连接这两者,则应确保您具有公用IP地址。