【问题标题】:Multithreaded TCP server and client多线程 TCP 服务器和客户端
【发布时间】:2016-09-26 15:34:05
【问题描述】:

在问这个问题之前我只是四处寻找,寻找 C# 中 TCP Server 和 Client 的示例。

我找到了this 链接,我只是使用了链接给定的代码,但不幸的是出现了问题,我被卡住了!

以下代码是服务器(控制台)的完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace TCP_Server_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener serverSocket = new TcpListener(8888);
            int requestCount = 0;
            TcpClient clientSocket = default(TcpClient);
            serverSocket.Start();
            Console.WriteLine(" >> Server Started");
            clientSocket = serverSocket.AcceptTcpClient();
            Console.WriteLine(" >> Accept connection from client");
            requestCount = 0;

            while ((true))
            {
                try
                {
                    requestCount = requestCount + 1;
                    NetworkStream networkStream = clientSocket.GetStream();
                    byte[] bytesFrom = new byte[10025];
                    networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                    string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
                    Console.WriteLine(" >> Data from client - " + dataFromClient);
                    string serverResponse = "Last Message from client" + dataFromClient;
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                    Console.WriteLine(" >> " + serverResponse);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }

            clientSocket.Close();
            serverSocket.Stop();
            Console.WriteLine(" >> exit");
            Console.ReadLine();
        }
    }
}

/*HandleClient Class */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TCP_Server_Console
{
    public class HandleClient
    {
        TcpClient clientSocket;
        string clNo;

        public void startClient(TcpClient inClientSocket, string clineNo)
        {
            this.clientSocket = inClientSocket;
            this.clNo = clineNo;
            Thread ctThread = new Thread(doChat);
            ctThread.Start();
        }

        private void doChat()
        {
            int requestCount = 0;
            byte[] bytesFrom = new byte[10025];
            string dataFromClient = null;
            Byte[] sendBytes = null;
            string serverResponse = null;
            string rCount = null;
            requestCount = 0;

            while ((true))
            {
                try
                {
                    requestCount = requestCount + 1;
                    NetworkStream networkStream = clientSocket.GetStream();
                    networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                    dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
                    Console.WriteLine(" >> " + "From client-" + clNo + dataFromClient);
                    rCount = Convert.ToString(requestCount);
                    serverResponse = "Server to clinet(" + clNo + ") " + rCount;
                    sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                    Console.WriteLine(" >> " + serverResponse);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(" >> " + ex.ToString());
                }
            }
        }
    }
}

以下代码是客户端(Windows Forms)的完整代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TCP_Client_Sample
{
    public partial class Form1 : Form
    {
        System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
        NetworkStream serverStream;

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            label_status.Text = "Client Started, Connecting...";

            try 
            {
                clientSocket.Connect("127.0.0.1", 8888);

                if (clientSocket.Connected)
                {
                    label_status.Text = "Connected";
                    label_status.ForeColor = Color.Green;
                }
             }
             catch (Exception xe) 
             {
                  MessageBox.Show("OOPS!!! SERVER MUST BE STARTED FIRST! \n\n" + xe.ToString());
             }
        }

        //Function to Send Message to Server (On Button Click)
        private void btn_send_Click(object sender, EventArgs e)
        {
            try 
            {
                NetworkStream serverStream = clientSocket.GetStream();
                byte[] outStream = System.Text.Encoding.ASCII.GetBytes("Message From Client$");
                serverStream.Write(outStream, 0, outStream.Length);
                serverStream.Flush();
                byte[] inStream = new byte[10025];
                serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
                string returnData = System.Text.Encoding.ASCII.GetString(inStream);
                chatBox.AppendText(">> Server: " + returnData);
            }
            catch (Exception ex) 
            {
                MessageBox.Show("Unable to Send Data: " + ex);
            }
        }
    }
}

每次我执行服务器代码时,它都会工作并启动。但是当我执行客户端时,服务器会抛出错误

指定的参数超出范围

这是完整的错误:

System.ArgumentOutOfRangeException:指定的参数超出了有效值的范围。

参数名称:尺寸

在 System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量,Int32 大小)
在 TCP_Server_Console.Program.Main(String[] args) 在 C:\Users\user\Documents\Visual Studio 2015\Projects\TCP_Server_Console\TCP_Server_Console\Program.cs:line 50

每次单击客户端表单中的btn_send 时,我也会收到相同的错误。

我被困在这里,我不知道是什么问题,因为这是我第一次使用 TCP Socket。

谁能帮帮我?

【问题讨论】:

  • 对我来说,这是编写大量代码的方式。你能把范围缩小到真正重要的东西吗?
  • @UweKeim - 很抱歉,尽管发布完整代码会更好。
  • 你将btye数组声明为10025,然后使用recievebuffersize读取了多个字节,这表明它们不一样。
  • @BugFinder - 你能更具体一点吗?我不明白这个问题。感谢您的宝贵时间!
  • 客户端不应连接到环回地址 127.0.0.1 :clientSocket.Connect("127.0.0.1", 8888);。客户端需要连接到PC的IP地址。服务器正在侦听此地址,这可能是错误的原因。

标签: c# multithreading sockets tcp


【解决方案1】:

问题在于你的代码使用了两种不同的尺寸

byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);

在这。你为 10025 字节预留了空间,但 RecieveBufferSize 可能是另一个大小,更大或更小,但如果更大,就会出错。

如果您将 read 调用调用的长度与字节数组的长度相同,您就不会遇到问题。

【讨论】:

    猜你喜欢
    • 2019-04-18
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多