簡體   English   中英

在C#中從客戶端向服務器發送字符串

[英]Sending a string to a server from a client in C#

我正在編寫一個簡單的測試程序,用於將字符串從客戶端發送到服務器,然后在服務器程序上顯示文本。 我該怎么做呢

這是我的客戶端代碼。

using System;
using System.Net;
using System.Net.Sockets;


    class client
    {

        static String hostName = Dns.GetHostName();

        public static void Main(String[] args)
        {
            String test = Console.ReadLine();

            IPHostEntry ipEntry = Dns.GetHostByName(hostName);
            IPAddress[] addr = ipEntry.AddressList;

            //The first one in the array is the ip address of the hostname
           IPAddress ipAddress = addr[0];


            TcpClient client = new TcpClient();

            //First parameter is Hostname or IP, second parameter is port on which server is listening
            client.Connect(ipAddress, 8);


            client.Close();
        }
    }

這是我的服務器代碼

using System;
using System.Net;
using System.Net.Sockets;

class server
{
    static int port = 8;
    static String hostName = Dns.GetHostName();
    static IPAddress ipAddress;

    public static void Main(String[] args)
    {
        IPHostEntry ipEntry = Dns.GetHostByName(hostName);

        //Get a list of possible ip addresses
        IPAddress[] addr = ipEntry.AddressList;

        //The first one in the array is the ip address of the hostname
        ipAddress = addr[0];

        TcpListener server = new TcpListener(ipAddress,port);

        Console.Write("Listening for Connections on " + hostName + "...\n");

        //start listening for connections
        server.Start();

        //Accept the connection from the client, you are now connected
        Socket connection = server.AcceptSocket();

        Console.Write("You are now connected to the server\n\n");


        int pauseTime = 10000;
        System.Threading.Thread.Sleep(pauseTime);

        connection.Close();


    }


}

您可以在Socket上使用SendReceive重載。 通過BeginSomethingEndSomething方法也存在異步版本。

你發送原始字節,所以你需要決定一個簡單的協議。 要發送一些文本,請選擇編碼(我將使用UTF-8)並使用Encoding.GetBytes獲取原始字節。

例:

Byte[] bytes = Encoding.UTF8.GetBytes("Royale With Cheese");

UTF8是Encoding類的靜態屬性,它是為了您的方便。

然后,您可以使用以下命令將數據發送到服務器/客戶端:

int sent = connection.Send(bytes);

接收:

Byte[] bytes = new Bytes[100]; 
int received = connection.Receive(bytes);

這看起來很簡單,但有一些警告。 可以隨時刪除連接,因此您必須為異常做好准備,尤其是SocketException 此外,如果您查看示例,您可以看到我sentreceived兩個變量。 它們保存實際發送的SendReceive字節數。 您不能依賴套接字發送或接收所有數據(尤其是在接收時不會,如果對方發送的數據少於您的預期會怎樣?)

一種方法是循環並發送,直到所有數據都表示為已發送:

var bytes = Encoding.UTF8.GetBytes("Royale With Cheese");
int count = 0;
while (count < bytes.Length) // if you are brave you can do it all in the condition.
{
    count += connection.Send(
        bytes, 
        count, 
        bytes.Length - count, // This can be anything as long as it doesn't overflow the buffer, bytes.
        SocketFlags.None)
}

SendReceive是同步的,它們會阻止,直到它們發送了一些內容。 您應該在套接字上設置某種超時值( Socket.SendTimeoutSocket.ReceiveTimeout 。)默認值為0,這意味着它們可能永遠阻塞。

接受怎么樣? 讓我們嘗試做一個類似的循環。

int count = 0;
var bytes = new Byte[100];
do
{
    count += connection.Receive(
        bytes,
        count,
        bytes.Length - count,
        SocketFlags.None);
} while (count < bytes.Length);

嗯。 那么......如果客戶端發送的數據少於100,會發生什么? 我們會阻塞,直到它達到超時,如果有,或者客戶端發送足夠的數據。 如果客戶端發送超過100個會發生什么? 您將只獲得100個第一個字節。

在你的情況下,我們可以嘗試閱讀非常少量和打印。 讀,打印,循環:

var sunIsBurning = true;
while (sunIsBurning) {
    var bytes = new Byte[16];
    int received = socket.Receive(bytes);
    if (received > 0)
        Console.Out.WriteLine("Got {0} bytes. START:{1}END;", received, Encoding.UTF8.GetString(bytes));
}

這里我們說“只要sunIsBurning接收16字節塊的數據,解碼為UTF-8”。 這意味着另一方發送的數據必須是UTF-8,否則您將獲得異常(它應該被您捕獲)這也意味着服務器只會在連接失敗時停止接收。

如果您已收到15個字節,並且客戶端終止連接,則永遠不會打印這15個字節。 你需要更好的錯誤處理:)

在大多數情況下,未捕獲的異常將終止您的應用程序; 不適合服務器。

“連接失敗”可能意味着很多事情 ,可能是連接被同伴重置或者你的網卡着火了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM