简体   繁体   English

在C#中从客户端向服务器发送字符串

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

I am writing a simple test program to send a string from a client to a server and then display the text on the server program. 我正在编写一个简单的测试程序,用于将字符串从客户端发送到服务器,然后在服务器程序上显示文本。 How would I go about doing this. 我该怎么做呢

Here is my client code. 这是我的客户端代码。

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

Here is my server code 这是我的服务器代码

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


    }


}

You can use the Send and Receive overloads on Socket . 您可以在Socket上使用SendReceive重载。 Asynchronous version exists as well, through the BeginSomething & EndSomething methods. 通过BeginSomethingEndSomething方法也存在异步版本。

You send raw bytes, so you'll need to decide upon a protocol however simple. 你发送原始字节,所以你需要决定一个简单的协议。 To send some text, select an encoding (I would use UTF-8) and get the raw bytes with Encoding.GetBytes . 要发送一些文本,请选择编码(我将使用UTF-8)并使用Encoding.GetBytes获取原始字节。

Example: 例:

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

UTF8 is a static property on the Encoding class, it's there for your convenience. UTF8是Encoding类的静态属性,它是为了您的方便。

You can then send the data to the server/client with: 然后,您可以使用以下命令将数据发送到服务器/客户端:

int sent = connection.Send(bytes);

Receive: 接收:

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

This looks easy, but there are caveats. 这看起来很简单,但有一些警告。 The connection may at any time be dropped, so you must be prepared for exceptions, especially SocketException . 可以随时删除连接,因此您必须为异常做好准备,尤其是SocketException Also if you look at the examples you can see that I have two variables sent and received . 此外,如果您查看示例,您可以看到我sentreceived两个变量。 They hold how many bytes Send and Receive actually sent. 它们保存实际发送的SendReceive字节数。 You cannot rely on the socket sending or receiving all the data (especially not when receiving, what if the other party sent less than you expected?) 您不能依赖套接字发送或接收所有数据(尤其是在接收时不会,如果对方发送的数据少于您的预期会怎样?)

One way to do this is too loop and send until all the data is indicated as sent: 一种方法是循环并发送,直到所有数据都表示为已发送:

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

Send and Receive are synchronous, they block until they've sent something. SendReceive是同步的,它们会阻止,直到它们发送了一些内容。 You should probably set some kind of timeout value on the socket ( Socket.SendTimeout & Socket.ReceiveTimeout .) The default is 0 which means they may block forever. 您应该在套接字上设置某种超时值( Socket.SendTimeoutSocket.ReceiveTimeout 。)默认值为0,这意味着它们可能永远阻塞。

Now how about receiving? 接受怎么样? Let's try to do a similar loop. 让我们尝试做一个类似的循环。

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

Hmm. 嗯。 Well... what happens if the client sends less than a 100? 那么......如果客户端发送的数据少于100,会发生什么? We would block until it hits the timeout, if there is one, or the client sends enough data. 我们会阻塞,直到它达到超时,如果有,或者客户端发送足够的数据。 What happens if the client sends more than a 100? 如果客户端发送超过100个会发生什么? You will only get the 100 first bytes. 您将只获得100个第一个字节。

In your case we could try reading very small amounts and print. 在你的情况下,我们可以尝试阅读非常少量和打印。 Read, print, loop: 读,打印,循环:

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

Here we say "receive data in 16 byte chunks as long as sunIsBurning, decode as UTF-8". 这里我们说“只要sunIsBurning接收16字节块的数据,解码为UTF-8”。 This means the data sent by the other party must be UTF-8 or you'll get an exception (it should probably be caught by you) This also means that the server will only stop receiving when the connection fails. 这意味着另一方发送的数据必须是UTF-8,否则您将获得异常(它应该被您捕获)这也意味着服务器只会在连接失败时停止接收。

If you have received 15 bytes, and the client kills the connection, those 15 bytes will never be printed. 如果您已收到15个字节,并且客户端终止连接,则永远不会打印这15个字节。 You will need better error handling for that :) 你需要更好的错误处理:)

An uncaught exception will kill your application in most cases; 在大多数情况下,未捕获的异常将终止您的应用程序; not desirable for a server. 不适合服务器。

"connection fails" could mean a lot of things , it might be that the connection was reset by the peer or your network card caught fire. “连接失败”可能意味着很多事情 ,可能是连接被同伴重置或者你的网卡着火了。

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

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