2015-05-29 2 views
0

У меня есть этот код клиента и сервера. Клиент:C# Multi threaded Server

namespace ClientTest 
{ 
internal class Program 
{ 
private static TcpClient client; 
private static NetworkStream stream; 
private static void Main(string[] args) 
{ 
string temp; 
client = new TcpClient("192.168.1.2",5052); 
stream = client.GetStream(); 
Console.WriteLine(client.SendBufferSize); 
while ((temp = Console.ReadLine()) != "exit") 
{ 
Send(temp); 
} 

Thread one=new Thread(()=> SendFile(new FileInfo(@"1.doc"))); 
one.Start(); 
Thread two=new Thread(()=> SendFile(new FileInfo(@"2.docx"))); 
two.Start(); 
// Console.ReadKey(true); 
} 

public static void SendFile(FileInfo file) 
{ 
stream = client.GetStream(); 
byte[] id = BitConverter.GetBytes((ushort)1); 
byte[] size = BitConverter.GetBytes(file.Length); 
byte[] fileName = Encoding.UTF8.GetBytes(file.Name); 
byte[] fileNameLength = BitConverter.GetBytes((ushort)fileName.Length); 
byte[] fileInfo = new byte[12 + fileName.Length]; 

id.CopyTo(fileInfo, 0); 
size.CopyTo(fileInfo, 2); 
fileNameLength.CopyTo(fileInfo, 10); 
fileName.CopyTo(fileInfo, 12); 

stream.Write(fileInfo, 0, fileInfo.Length); //Размер файла, имя 

byte[] buffer = new byte[1024 * 32]; 
int count; 

long sended = 0; 

using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open)) 
while ((count = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
{ 
stream.Write(buffer, 0, count); 
sended += count; 
Console.WriteLine("{0} bytes sended.", sended); 
} 
stream.Flush(); 
} 

private static void Send(string message) 
{ 
byte[] id = BitConverter.GetBytes((ushort)0); 
byte[] msg = Encoding.UTF8.GetBytes(message); 
byte[] msgLength = BitConverter.GetBytes((ushort)msg.Length); 
byte[] fileInfo = new byte[12 + msg.Length]; 

id.CopyTo(fileInfo, 0); 
msgLength.CopyTo(fileInfo, 10); 
msg.CopyTo(fileInfo, 12); 
stream.Write(fileInfo, 0, fileInfo.Length); 
stream.Flush(); 

} 
} 
} 

Сервер:

namespace Server_Test 
{ 
class Server 
{ 
    static void Main(string[] args) 
    { 
     Server serv = new Server(); 
    } 
    private TcpListener listener { get; set; } 
    private NetworkStream stream { get; set; } 

    public Server() 
    { 
     listener = new TcpListener(IPAddress.Parse("192.168.1.2"), 5052); 
     listener.Start(); 
     new Thread(ListenForClients).Start(); 
    } 

    private void ListenForClients() 
    { 
     while (true) 
     { 
      TcpClient client = this.listener.AcceptTcpClient(); 
      new Thread(HandleClient).Start(client); 
     } 
    } 

    private void HandleClient(object tcpClient) 
    { 
     TcpClient client = (TcpClient)tcpClient; 
     while (client.Connected) 
     { 

      Recieve(client); 
     } 
    } 

    private void Recieve(TcpClient client) 
    { 
     byte[] buffer = new byte[client.ReceiveBufferSize]; 
     try 
     { 
      stream = client.GetStream(); 
      int bytesRead = stream.Read(buffer, 0, 12); 
      if (bytesRead == 0) return; 

      ushort id = BitConverter.ToUInt16(buffer, 0); 
      long len = BitConverter.ToInt64(buffer, 2); 
      ushort nameLen = BitConverter.ToUInt16(buffer, 10); 
      stream.Read(buffer, 0, nameLen); 
      string fileName = Encoding.UTF8.GetString(buffer, 0, nameLen); 

      if (id == 1) 
      { 
       using (BinaryWriter writer = new BinaryWriter(new  FileStream(fileName, FileMode.Create))) 
       { 
        int recieved = 0; 
        while (recieved < len) 
        { 
         bytesRead = stream.Read(buffer, 0, client.ReceiveBufferSize); 
         recieved += bytesRead; 
         writer.Write(buffer, 0, bytesRead); 
         Console.WriteLine("{0} bytes recieved.", recieved); 
        } 
       } 
       Console.WriteLine("File length: {0}", len); 
       Console.WriteLine("File Name: {0}", fileName); 
       Console.WriteLine("Recieved!"); 
      } 
      else 
      { 
       Console.WriteLine(fileName); 
      } 
     } 
     catch (Exception ex) 
     { 

      stream.Close(); 
      client.Close(); 
      Console.WriteLine(ex); 
     } 
     finally 
     { 
      stream.Flush(); 
     } 
    } 
} 
} 

Проблема: я не могу отправить 2 файлов в потоках. Если я отправлю 1 файл, сервер получит его и правильно сохранит. Какие изменения необходимы в этом коде, чтобы клиент мог переносить 2 или более файлов и позволить серверу получать его? UDP. Добавлен модифицированный SendFile, но не работает.

public static void SendFile(FileInfo file) 
    { 
     TcpClient client; 
     NetworkStream stream; 
     client = new TcpClient("192.168.1.2", 5052); 
     stream = client.GetStream(); 
     byte[] id = BitConverter.GetBytes((ushort)1); 
     byte[] size = BitConverter.GetBytes(file.Length); 
     byte[] fileName = Encoding.UTF8.GetBytes(file.Name); 
     byte[] fileNameLength = BitConverter.GetBytes((ushort)fileName.Length); 
     byte[] fileInfo = new byte[12 + fileName.Length]; 

     id.CopyTo(fileInfo, 0); 
     size.CopyTo(fileInfo, 2); 
     fileNameLength.CopyTo(fileInfo, 10); 
     fileName.CopyTo(fileInfo, 12); 

     stream.Write(fileInfo, 0, fileInfo.Length); //Размер файла, имя 

     byte[] buffer = new byte[1024 * 32]; 
     int count; 

     long sended = 0; 

     using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open)) 
      while ((count = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       stream.Write(buffer, 0, count); 
       sended += count; 
       Console.WriteLine("{0} bytes sended.", sended); 
      } 
    } 
+0

Вы не можете отправить на одном потоке двух различных файлов одновременно. Либо вам нужно сделать 2 подключения, либо отправить файлы последовательно. –

+0

Итак, какие изменения мне нужно сделать в этом коде? – 1L1dan

+0

Метод 'SendFile' должен создавать' TcpClient', а не метод 'Main'. Каждый метод отправки должен иметь свое собственное соединение. –

ответ

2

На стороне клиента, ваши два отдельных отправки потоков не могут совместно использовать тот же экземпляр client = new TcpClient("192.168.1.2",5052); одновременно посылать данные. Каждый поток должен иметь свой собственный экземпляр. Обратите внимание, однако, что для двух клиентских сокетов это нормально, чтобы одновременно удалять один и тот же IP-порт на стороне сервера. Это просто, что исходящий порт на стороне клиента должен быть разным между двумя соединениями. Когда вы создаете дополнительное исходящее TCP-соединение на клиенте, TcpClient будет автоматически использовать следующий доступный исходящий порт.

Например, вы могли бы попробовать что-то вроде следующего:

internal class Program 
{ 
private static void Main(string[] args) 
{ 
    SenderThreadClass stc1 = SenderThreadClass("192.168.1.2", 5052); 
    SenderThreadClass stc2 = SenderThreadClass("192.168.1.2", 5052); 
    Thread one = new Thread(()=> stc1.SendFile(new FileInfo(@"1.doc"))); 
    one.Start(); 
    Thread two = new Thread(()=> stc2.SendFile(new FileInfo(@"2.docx"))); 
    two.Start(); 
} 
} 

public class SenderThreadClass 
{ 
private TcpClient client; 
private NetworkStream stream; 

public SenderThreadClass(string serverIP, int serverPort) 
{ 
    client = new TcpClient(serverIP, serverPort); 
    stream = client.GetStream(); 
} 

public void SendFile(FileInfo file) 
{ 
byte[] id = BitConverter.GetBytes((ushort)1); 
byte[] size = BitConverter.GetBytes(file.Length); 
byte[] fileName = Encoding.UTF8.GetBytes(file.Name); 
byte[] fileNameLength = BitConverter.GetBytes((ushort)fileName.Length); 
byte[] fileInfo = new byte[12 + fileName.Length]; 

id.CopyTo(fileInfo, 0); 
size.CopyTo(fileInfo, 2); 
fileNameLength.CopyTo(fileInfo, 10); 
fileName.CopyTo(fileInfo, 12); 

stream.Write(fileInfo, 0, fileInfo.Length); //Размер файла, имя 

byte[] buffer = new byte[1024 * 32]; 
int count; 
long sended = 0; 

using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open)) 
while ((count = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
{ 
stream.Write(buffer, 0, count); 
sended += count; 
Console.WriteLine("{0} bytes sended.", sended); 
} 
stream.Flush(); 
} 
} 
+0

Используя этот код, как он должен выглядеть? – 1L1dan

+0

Я только что привел пример кода. Это код не проверен компилятором, потому что у меня нет IDE передо мной, но он должен дать вам правильную идею о том, как действовать. –

+0

Хорошо, я попробую, спасибо! – 1L1dan