套接字通信在同一台机器上工作,但不在不同的机器之间工作

时间:2017-05-26 01:30:17

标签: c#

我写了一个客户端/服务器应用程序来发送文件。如果服务器和客户端在同一台机器上,它可以工作,但是当我将服务器放在另一台机器上时,当服务器读取套接字时,我会收到错误。

这是服务器的代码:

class conexion
{
    int sizeofonpacket = 9999;
    string filsc="";
    string titre = "";
    bool sendfilcomand = false;
    int conteur1 = 0;
    int conteur2 = 0;
    BinaryWriter sf;
    TcpListener listiner;
    TcpClient client;
    NetworkStream netStream;

    public conexion(IPAddress ip, int port)
    {
        listiner = new TcpListener(ip, port);
        listiner.Start();
        client = listiner.AcceptTcpClient();
        netStream = client.GetStream();
        Console.Write("client is present \r\n ");
    }

    public void read()
    {
        while (client.Connected)
        {
            string returndata;
            int size = 0;
            string c = "";
            byte[] bs = new byte[4];
            byte[] b = new byte[1];

            try
            {
                //read the comand of client "s" for string or "b" for binary file if it is "s" it read the string that client write
                //if it is "b" we read the string "dfgjsdgfjdsgfjhdsgfj" it is not important 
                Console.Write("ready \r\n ");
                netStream.Read(b, 0, 1);

                c = Encoding.UTF8.GetString(b);
                Console.WriteLine("\r\n comand  :" + c);
                b = new byte[4];
                netStream.Read(b, 0, 4);
                returndata = Encoding.UTF8.GetString(b);
                size = Int32.Parse(returndata);
                Console.WriteLine("\r\n size de packet int =" + size);
                b = new byte[size];
                netStream.Read(b, 0, size);
            }
            catch
            {
                Console.WriteLine("\r\n conexion echoue");
                listiner.Stop();
            }

            switch (c)
            {
                case "b":
                    if (sendfilcomand == false) //if sendfilcomand is false we read first the title
                    {
                        sendfilcomand = true;

                        break;
                    }
                    sendfilcomand = false;
                    filsc = titre;
                    Console.WriteLine("\r\nle titr est:" + titre);

                    titre = "";
                    sf = new BinaryWriter(new FileStream(filsc, FileMode.Create));

                    conteur2 = 0;
                    conteur1 = size;
                    crebfile(b);
                    Console.WriteLine("\r\n creat file for " + conteur2 + " to " + conteur1);
                    b = new byte[sizeofonpacket];
                    while (size != 0)
                    {
                        try
                        {
                            netStream.Read(bs, 0, 4);

                            returndata = Encoding.UTF8.GetString(bs);
                            size = Int32.Parse(returndata);

                            conteur1 = size;
                            Console.WriteLine("sizee a get" + size);

                            if (size == 0)
                            {
                                Console.WriteLine("yout est termine");
                                sf.Close();
                                conteur1 = 0;
                                conteur2 = 0;
                                break;
                            }
                            else if (size != sizeofonpacket)
                            {
                                b = new byte[size];
                            }
                            netStream.Read(b, 0, size);
                        }
                        catch 
                        {
                            Console.WriteLine("\r\n imposible to read ");
                        }

                        crebfile(b);
                        b.Initialize();
                    }

                    sf.Close();
                    conteur1 = 0;
                    conteur2 = 0;
                    break;

                case "s":
                    returndata = Encoding.UTF8.GetString(b);
                    Console.WriteLine("\r\n" + returndata);

                    if (sendfilcomand)
                    {
                        titre = returndata;
                        Console.WriteLine("titre a get" + titre);

                        break;
                    }
                    break;

                default:
                    Console.WriteLine("\r\n rien comand");
                    break;
            }
        }
    }

    public string quadripl(string s)
    {
        while (s.Length < 4)
        {
            s = "0" + s;
        }
        return s;
    }

    public void crebfile(byte[] byts)
    {
        try
        {
            sf.Write(byts, 0, conteur1);
        }
        catch
        {
            Console.WriteLine("imposible de crer le fichier");
        }
    }
}

以下是客户端代码:

class conexion
{
    string filsr;
    int sizeofonpacket = 9999;
    bool sendfilcomand = false;
    bool getfilcomand = false;
    int bali;
    int fali;
    Stream file;
    TcpListener listiner;
    TcpClient client;
    NetworkStream netStream;

    public conexion(string ip, int port)
    {
        listiner = null;
        Console.Write("star client ");
        client = new TcpClient(ip, 3568);
        netStream = client.GetStream();
    }

    public void send()
    {
        while (client.Connected)
        {
            //enter the comand "s" or "b"
            string c = "";
            Console.WriteLine("\r\n ecrir comand:");
            c = Console.ReadLine();

            string s = "";
            if (c == "s")
            {
                Console.WriteLine("\r\n entrer string:");
                s = Console.ReadLine();
            }
            string size = "";
            Byte[] sendBytes = null;
            //try
            {
                switch (c)
                {
                    case "b":
                        Console.WriteLine("\r\n comand binary file");
                        netStream.Write(Encoding.UTF8.GetBytes(c), 0, 1);
                        if (sendfilcomand == false) //we will first send the patsh of file after we will send data of file
                        {
                            sendBytes = Encoding.UTF8.GetBytes("dfgjsdgfjdsgfjhdsgfj"); //this is not important
                            size = quadripl(sendBytes.Length.ToString());
                            netStream.Write(Encoding.UTF8.GetBytes(size), 0, Encoding.UTF8.GetBytes(size).Length);
                            netStream.Write(sendBytes, 0, sendBytes.Length);
                            sendfilcomand = true;
                            s = getitr();
                            c = "s";
                            goto case "s";
                        }
                        sendfilcomand = false; //now we will send data
                        filsr = actitr(); //the title is save in "C:/Users/Ce-Pc/Desktop/titreactuel.txt"
                        file = new FileStream(filsr, FileMode.Open);
                        fali = (int)file.Length;
                        bali = 0;
                        byte[] bs = new byte[4];
                        Console.WriteLine("\r\n star sending ");
                        do
                        {

                            sendBytes = filebtobyte(filsr); //read part of file to send
                            Console.WriteLine("\r\n terminer " + bali + " " + " " + fali);
                            size = quadripl(sendBytes.Length.ToString()); //just for add the zero
                            Console.WriteLine("\r\n le size de fichier binair est " + size);
                            netStream.Write(Encoding.UTF8.GetBytes(size), 0, Encoding.UTF8.GetBytes(size).Length);

                            netStream.Write(sendBytes, 0, sendBytes.Length);

                        } while (bali != -1); //when we come to last part of the file (filebtobyte give -1 to bali)
                        bali = 0;
                        size = quadripl("0");
                        Console.WriteLine("\r\n terminer fiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiin ");
                        netStream.Write(Encoding.UTF8.GetBytes(size), 0, Encoding.UTF8.GetBytes(size).Length);
                        netStream.Read(bs, 0, 4);
                        break;
                    case "s":
                        Console.WriteLine("\r\n comand string");
                        netStream.Write(Encoding.UTF8.GetBytes(c), 0, 1);
                        size = quadripl(s.Length.ToString());
                        sendBytes = Encoding.UTF8.GetBytes(size);
                        Console.WriteLine("\r\n size=" + size);
                        netStream.Write(sendBytes, 0, sendBytes.Length);
                        sendBytes = Encoding.UTF8.GetBytes(s);
                        netStream.Write(sendBytes, 0, sendBytes.Length);

                        if (sendfilcomand)
                        {
                            c = "b";
                            goto case "b";
                        }
                        break;
                    default:
                        Console.WriteLine("\r\n rien comand");
                        break;
                }
            }
            catch
            {
                Console.WriteLine("\r\n imposible de transfer");
            }
        }
        Console.Write("client est deconect \r\n ");
    }

 //////////////////the functions//////////////////////////////////

    public byte[] filebtobyte(string s)
    {
        byte[] byts = null;
        try
        {
            if (fali - bali < sizeofonpacket)
            {
                byts = new byte[fali - bali];
                file.Read(byts, 0, fali - bali);
                file.Close();
                bali = -1;
            }
            else
            {
                byts = new byte[sizeofonpacket];
                file.Read(byts, 0, sizeofonpacket);
                bali += sizeofonpacket;
            }
        }
        catch
        {
            Console.WriteLine("imposible de trouver le fichier");
        }
        return byts;
    }
    public string quadripl(string s)
    {
        while (s.Length < 4)
        { s = "0" + s; }
        return s;
    }

    public string getitr()
    {
        StreamReader titrfil = new StreamReader("C:/Users/Ce-Pc/Desktop/titre.txt");
        string sss = "";
        try
        {
            sss = titrfil.ReadLine();
            Console.WriteLine("\r\n le chemin " + sss);
            titrfil.Close();
        }
        catch
        {
            Console.WriteLine("\r\n imposible");
        }
        return sss;
    }
    public string actitr()
    {
        StreamReader titrfil = new StreamReader("C:/Users/Ce-Pc/Desktop/titreactuel.txt");
        string sss = "";
        try
        {
            sss = titrfil.ReadLine();
            Console.WriteLine("\r\n le chemin " + sss);
            titrfil.Close();
        }
        catch
        {
            Console.WriteLine("\r\n imposible");
        }
        return sss;
    }
}

2 个答案:

答案 0 :(得分:0)

您是否在两台机器之间检查了防火墙?

尝试从客户端PC上的命令提示符进行telnet测试,以连接到服务器PC上的端口:

telnet <server ip> 3568

如果失败,则网络级别存在问题(可能与防火墙有关)。

另外,请仔细检查您是否为客户端和服务器使用相同的端口(您不会在上面的代码中显示服务器端口)

答案 1 :(得分:0)

您的代码已被删除,我不知道您输入了什么内容,因此我无法准确预测答案。以下是4种可能的答案:

请阅读整个答案

  • 防火墙可能会阻止连接(正如Ryan所说)。您可以在控制面板中将其禁用
  • 确保输入正确的服务器地址以启动TCP侦听器(从不使用本地默认IP: 127.0.0.1 )。要找到正确的IP地址,请在“无线LAN适配器Wi-Fi:&#39;”部分中打开cmd,键入&#39; ipconfig&#39;,复制 Ipv4地址。对于客户端,您必须输入从其他计算机生成的Ipv4地址。 Ipv4以黄色突出显示。enter image description here

  • 如果两种解决方案都不起作用,那么我必须问你是否在同一个无线网络中。如果没有,那么如果你从互联网上的实时服务器而不是在路由器中运行它,它就不会(当然)工作。

  • 如果客户端/服务器中没有错误,那么它必须与您的代码一起发送/接收。通过互联网发送byte []并不能保证对方将整体接收它(它被分成小包),你的代码必须知道何时开始接收以及何时停止接收。您可以在数据的开头添加一个小标题,用于说明文件的长度以及剩余的字节数。

更新

您希望整体接收数据,而不是小块。所以我创建了一些可以帮助您更轻松地发送和接收数据的函数:

static void sendMessage(string c_1)
    {
        byte[] command = Encoding.ASCII.GetBytes(c_1);
        byte[] commandLength = Encoding.ASCII.GetBytes(command.Length.ToString());
        List<byte> commandLengthInByteArray = commandLength.ToList();
        while (true)
        {
            if (commandLengthInByteArray.ToArray().Length < 50)
            {
                commandLengthInByteArray.Add(Convert.ToByte('x'));
            }
            else
            {
                break;
            }
        }
        byte[] parsedCommandLength = commandLengthInByteArray.ToArray();
        sck.Send(parsedCommandLength);
        sck.Send(command);
    }
    static void sendMessage_ftp(byte[] data)
    {
        byte[] commandLength = Encoding.ASCII.GetBytes(data.Length.ToString());
        List<byte> commandLengthInByteArray = commandLength.ToList();
        while (true)
        {
            if (commandLengthInByteArray.ToArray().Length < 50)
            {
                commandLengthInByteArray.Add(Convert.ToByte('x'));
            }
            else
            {
                break;
            }
        }
        byte[] parsedCommandLength = commandLengthInByteArray.ToArray();
        sck.Send(parsedCommandLength);
        sck.Send(data);
    }

static byte[] getResponse(Socket sck)
    {
        byte[] CommandLengthInByteArray = ReadBytes(50, sck);
        List<byte> commandLengthInByteArrayList = new List<byte>();
        foreach (byte b in CommandLengthInByteArray)
        {
            if (b.ToString() != "120")
            {
                commandLengthInByteArrayList.Add(b);
            }
        }
        Int32 fileSize = Convert.ToInt32(Encoding.ASCII.GetString(commandLengthInByteArrayList.ToArray()));
        byte[] data = ReadBytes(fileSize, sck);
        return data;
    }
    static byte[] ReadBytes(Int32 size, Socket sck)
    {
        //The size of the amount of bytes you want to recieve, eg 1024
        var bytes = new byte[size];
        Int32 total = 0;
        do
        {
            var read = sck.Receive(bytes, total, size - Convert.ToInt32(total), SocketFlags.None);
            if (read == 0)
            {
                //If it gets here and you received 0 bytes it means that the Socket has Disconnected gracefully (without throwing exception) so you will need to handle that here
            }
            total += read;
            //If you have sent 1024 bytes and Receive only 512 then it wil continue to recieve in the correct index thus when total is equal to 1024 you will have recieved all the bytes
        } while (total != size);
        return bytes;
    }

如何使用它:

  • 发送文字:sendMessage("SomeTextHere");
  • 发送文件(&gt; 1 GB)sendMessage_ftp(File.ReadAllBytes(@"C:\Users\StackExchange\Desktop\Image.png"));

  • 要接收整个文件或文字(不是我的作品):

      
        

    byte[] messageOrFile = getResponse(sck);

                

但是...

您必须摆脱使用TcpClient,而是使用System.Net.Sockets

您必须:

  • TcpClient client;替换为Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

  • client = listiner.AcceptTcpClient();替换为client = listiner.AcceptSocket();