2011-02-11 142 views
5

我正在编写一个简单的测试程序,将字符串从客户端发送到服务器,然后在服务器程序上显示文本。我将如何去做这件事。从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(); 


    } 


} 

回答

8

您可以使用SendReceive重载上Socket。异步版本也存在,通过方法BeginSomething & EndSomething方法。

你发送原始字节,所以你需要决定一个协议,但很简单。要发送一些文本,请选择一种编码(我将使用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.SendTimeout & Socket.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,解码为UTF-8接收16个字节的块数据”。这意味着对方发送的数据必须是UTF-8,否则您将得到一个异常(它可能会被您捕获)。这也意味着服务器只会在连接失败时停止接收。

如果您收到了15个字节,并且客户端终止了连接,那么这15个字节将永远不会被打印。您将需要更好的错误处理:)

在大多数情况下,未捕获的异常将会终止您的应用程序;不适合服务器。

“连接失败”可能意味着a lot of things,可能是由对等设备重置了连接或者您的网卡着火了。

相关问题