C#多线程服务器

时间:2015-05-29 02:42:48

标签: c# multithreading sockets tcp 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);
            }
    }

1 个答案:

答案 0 :(得分:2)

在客户端,您的两个独立发送线程无法共享同一个client = new TcpClient("192.168.1.2",5052);实例以同时发送数据。每个线程都应该有自己的实例。但请注意,2个客户端套接字可以同时访问同一服务器端IP:端口。只是客户端的出站端口必须在2个连接之间不同。在客户端上创建其他出站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();
}
}