2013-07-26 3 views
0

Я новичок в сети на C#, и у меня возникают проблемы с базовым клиент-сервером. Сервер работает нормально, но когда сервер встает и клиент пытается подключиться, он выдает ошибку «сокет не должен быть связан или подключен». Дополнительные сведения о том, что сервер и клиент выполняются на одном компьютере с отключенным исключениемAddressUse.TCP-сокеты - InvalidOperationException

код клиента:

this.client = new TcpClient(this.settings.GetByName("MasterServerIP").Value, int.Parse(this.settings.GetByName("MasterServerPort").Value)) { ExclusiveAddressUse = false }; 
this.client.Connect(IPAddress.Parse(this.settings.GetByName("MasterServerIP").Value), int.Parse(this.settings.GetByName("MasterServerPort").Value)); 
this.writer = new BinaryWriter(this.client.GetStream()); 
this.reader = new BinaryReader(this.client.GetStream()); 

Серверный код:

this.Listener.Start(); 
TcpClient tcpClient; 
while (this.Listener.Server.Connected) 
{ 
tcpClient = this.Listener.AcceptTcpClient(); 
System.Threading.Thread t = new System.Threading.Thread(() => { this.ProcessClient(tcpClient); }); //Runs the thing on another thread so this can be accepting another client 
t.Start(); 
} 

Edit: Даже при снятии подключения вызова метода, он по-прежнему бросает ту же ошибку. Любая помощь?

+1

Пожалуйста, не редактируйте свой вопрос, чтобы удалить соответствующую деталь. Это прекрасно, чтобы _augment_ информацию, но внося изменения, которые недействительны на все ответы на сегодняшний день, «нарушает» концепцию q & a. – paxdiablo

+0

Извините, я просто подумал, что я удалю его, чтобы люди больше не указывали на это (если они не видели ответов) – user1763295

+0

Это нормально, просто добавьте редактирование в конец вопроса о том, что оно кажется ошибкой даже без второго соединения, и что ошибка находится в вызове конструктора. И дайте нам фактический номер ошибки из socketexception, а также :-) – paxdiablo

ответ

1

При создании TCPClient с хостом и портом он автоматически подключается. Затем вам не нужно снова подключаться.

Для получения более подробной информации см. http://msdn.microsoft.com/en-us/library/System.Net.Sockets.TcpClient(v=vs.110).aspx.

Что касается вашего комментария, что он по-прежнему не работает, когда вы удаляете вызов соединения, либо вы все еще используете другой код, либо что-то еще не так. Следующий код работает отлично:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net.Sockets; 
namespace testtcp { 
    class Program { 
     static void Main(string[] args) { 
      TcpClient client = new TcpClient("www.google.com", 80); 
      //client.Connect("www.microsoft.com", 80); 
     } 
    } 
} 

, но, в тот момент, раскомментировать Connect вызов, вы получите SocketException с expanatory текстом:

{"A connect request was made on an already connected socket"} 

Однако, это на самом деле другое сообщение ошибки в тот, который вы получаете, заставляя нас поверить в утверждение «есть что-то еще неправильное» сверху.

Если изучить интернет-документы для TcpClient.ExclusiveAddressUsehere, вы увидите следующий фрагмент кода (мой жирный):

Это свойство должно быть установлено до того, как основной сокет связан с клиентским портом. Если вы вызываете Connect, BeginConnect, TcpClient(IPEndPoint), или TcpClient(String, Int32), порт клиента связан как побочный эффект метода, и впоследствии вы не можете установить свойство ExclusiveAddressUse.

И действительно, следующий код:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net.Sockets; 
namespace testtcp { 
    class Program { 
     static void Main(string[] args) { 
      TcpClient client = new TcpClient("www.google.com", 80) { 
       ExclusiveAddressUse = false 
      }; 
     } 
    } 
} 

дает исключение в точный вы описываете.

Таким образом, нижняя линия, если вы хотите использовать ExclusiveAddressUse, не пытайтесь использовать его с конструктором хост-а-порте, так что будет связывать сокет и попытку изменить свойство, то возбудит исключение , Вместо этого (как одна возможность) используйте конструктор без аргументов, измените свойство, и , затем connect.

+0

По-прежнему бросать сообщение об ошибке после удаления вызова метода соединения. – user1763295

+1

@ user1763295 Я предлагаю, что это не так. Я предлагаю вам не запускать исправленный код. – EJP

+0

@ EJP, на самом деле получается, что это _was_ true. Ошибка представляет собой комбинацию выбора конструктора (тот, который связывается), а также пытается изменить свойство, которое невозможно изменить после привязки. – paxdiablo

1

Проблема заключается в первых двух строках кода клиента:

this.client = new TcpClient(this.settings.GetByName("MasterServerIP").Value, int.Parse(this.settings.GetByName("MasterServerPort").Value)) { ExclusiveAddressUse = false }; 
this.client.Connect(IPAddress.Parse(this.settings.GetByName("MasterServerIP").Value), int.Parse(this.settings.GetByName("MasterServerPort").Value)); 

Когда вы звоните в конструкторе на первой линии, вы уже подключения TcpClient, поэтому вызов Connect после недействителен , Удалите его, и он будет работать.

С docs, конструктор:

Инициализирует новый экземпляр класса TcpClient и соединяется с указанным портом на указанном хосте.

+0

Я удалил соединение, и он по-прежнему бросает ту же ошибку. – user1763295

+0

Да, это странно. Выбрасывает ошибку на сервере или на клиенте? И на какой линии? – Dirbaio

+0

Он бросает его на строку, где я его определяю (this.client = new TcpClient и т. Д.). И просто для добавления дополнительной информации я не установил для нее значение (частный клиент TcpClient;) – user1763295

Смежные вопросы