开发者

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. Asynchronous version exists as well, through the BeginSomething & EndSomething methods.

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.

Example:

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

UTF8 is a static property on the Encoding class, it's there for your convenience.

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. Also if you look at the examples you can see that I have two variables sent and received. They hold how many bytes Send and Receive actually sent. 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. 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.

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? 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? You will only get the 100 first bytes.

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". 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.

If you have received 15 bytes, and the client kills the connection, those 15 bytes will never be printed. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜