简体   繁体   English

多线程 TCP 服务器和客户端

[英]Multithreaded TCP server and client

I just search around before asking this problem, looking for example of TCP Server and Client in C#.我只是在问这个问题之前四处搜索,寻找 C# 中的 TCP 服务器和客户端的示例。

I found this link, I just used the given code by the link but unfortunately there's a problem and I'm stuck!我找到了这个链接,我只是使用了链接给出的代码,但不幸的是有一个问题,我被卡住了!

The following code is the complete code for server (console):以下代码是服务器(控制台)的完整代码:

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());
                }
            }
        }
    }
}

The following code is the complete code for client (Windows Forms):以下代码是客户端(Windows 窗体)的完整代码:

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);
            }
        }
    }
}

Every time I execute the code of server it works and started.每次我执行服务器代码时,它都会工作并启动。 But when I execute the client, the server throws an error但是当我执行客户端时,服务器会抛出错误

Specified Argument was out of the range指定的参数超出范围

Here is the complete error:这是完整的错误:

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. System.ArgumentOutOfRangeException:指定的参数超出了有效值的范围。

Parameter name: size参数名称:尺寸

at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)在 System.Net.Sockets.NetworkStream.Read(字节 [] 缓冲区,Int32 偏移量,Int32 大小)
at TCP_Server_Console.Program.Main(String[] args) in C:\Users\user\Documents\Visual Studio 2015\Projects\TCP_Server_Console\TCP_Server_Console\Program.cs:line 50在 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

I'm also getting the same error every time I click the btn_send from client form.每次单击客户端表单中的btn_send时,我也会收到相同的错误。

I am stuck here and I don't know what's the problem since this is the first time I'm work with TCP Socket.我被困在这里,我不知道问题出在哪里,因为这是我第一次使用 TCP Socket。

Can anynone help me?任何人都可以帮助我吗?

The problem lies in that your code used two different sizes问题在于您的代码使用了两种不同的大小

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

In this.在这。 Youve reserved space for 10025 bytes, but RecieveBufferSize maybe another size, bigger or smaller, but if bigger, it will error.您为 10025 字节保留了空间,但 RecieveBufferSize 可能是另一个大小,更大或更小,但如果更大,它会出错。

If you make the read call call the same length as your byte array you wont have your problem.如果您将读取调用调用与字节数组的长度相同,您将不会遇到问题。

            byte[] inStream = new byte[10025];
            byte[] tStream = new byte[(int)clientSocket.ReceiveBufferSize];

            serverStream.Read(tStream, 0, (int)clientSocket.ReceiveBufferSize);

Would be the quick easy fix to ensure that the byte buffer its reading into will always be the correct size needed.将是确保其读取的字节缓冲区始终是所需的正确大小的快速简单修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM