Я хочу создать клиентскую и серверную программу, которая будет отправлять объект между собой и заставлять его работать так, чтобы две программы могли обмениваться данными через две отдельные хост-системы.
Запуск обеих программ на одной хост-системе делает его работоспособным, но когда я пытаюсь запустить серверную и клиентскую программы на двух разных системах, я просто получаю сообщение об ошибке тайм-аута на стороне клиента. Был один странный случай, когда он работал, когда сервер работал на моем компьютере, а клиент - на моем рабочем ноутбуке. Однако при попытке подключиться к серверу с помощью другого ноутбука это не сработало. Он также не будет работать, если у меня есть сервер на моем ноутбуке и клиент на моем компьютере.
Код сервера:
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();
}
}
}
}
Клиент должен подключиться и начать запрашивать у пользователя ввести имя конкурса, а затем дату конкурса, но вместо этого я просто получаю сообщение об ошибке тайм-аута.