You can get moe info about Socket class
from MSDN http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx
or from baiuhttp://baike.baidu.com/view/13870.htm
How to use udpclient:http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx
<Draft blog, need to improve>
程序介绍:从一台机器发送数据包(基于TCPor UPD协议)到另一台远程的机器在发送一个数据包到另外一个远程机器的接口时,必须要保证远程机器的接口时有服务的,并且可以接受你所发送的数据包,否则将会出现如下错误,类似于“Noconnection could be made because the target machine actively refused it127.0.0.1:8000”,这说明你的数据包可以找到目的机器,但是却不能被目的机器的接口接受,因为目的机器的接口没有服务,或者服务没有启动。怎么在远程目的机器的指定接口样建立一个服务呢? 我们可以写一个监听程序,监听目的接口。当然我们也可以写一个服务或者开发一个简易网站,绑定到这个接口。<我们的程序暂时以只是支持TCP数据包为例>
SourceMachine IP:10.80.225.111
DestinationMachine IP:157.55.69.198
注意事项:
1. 保证Source Machine的IP是正确的,如果你电脑是使用的是Wif接入网络,你应该提供WirelessNetwork Connection下的IP,如果是有线连接,则应该提供Ethernetadapter Local Area Connection下的IP(ipconfig/all)
2. 保证Destination machine IP是正确的,如果网络存在NAT的情况,应该在Source端的程序中提供NAT前的IP
3. 确保source端程序运行前,Destination端的监听程序已经运行,否则目的端端口没有服务,数据包将被拒绝
4. 确保发送端使用的协议和接收端使用的协议是一样的. 例如,如果接受端端口使用的是TCP协议,而发送端发送UPD数据包,那么发送端将会抛出异常like“The requested protocol has not been configured into the system, or no implementation for it exists“
5. 确保发送端的数据包是可以识别的, 例如接受端如果是80端口,并且有webservice在80端口,那么它只能接受固定格式数据包,例如
string request = "GET / HTTP/1.1\r\n" +
"Host:" + destIP + "\r\n" +
"Connection: Keep-Alive\r\n" +
"Keepalivetime: 30\r\n" +
"Keepaliveinterval: 15\r\n" +
"Keep-Alive: timeout=600\r\n\r\n";
这是一个httprequest的string形式。
如果发送下面的数据例如:string request = "AAAAAAAAAAAAAAAA";那么数据包是不可识别的。
6. 这里我将会使用一个常用的数据包monitor工具wireshark去捕获基于不同协议的数据包。 也可以用winpcap监控。
Wireless LANadapter Wireless Network Connection:
Connection-specific DNS Suffix . : corp.microsoft.com
Link-local IPv6 Address . . . . . :fe80::10b3:d3e9:2026:5fe8%11
IPv4 Address. . . . . . . . . . . : 10.80.224.27
Subnet Mask . . . . . . . . . . . :255.255.252.0
Default Gateway . . . . . . . . . :10.80.224.1
Ethernetadapter Local Area Connection:
Connection-specific DNS Suffix . : corp.microsoft.com
IPv6 Address. . . . . . . . . . . :2001:4898:e0:1012:5c7c:f9f1:5e81:d56
Temporary IPv6 Address. . . . . . :2001:4898:e0:1012:8c07:cdd2:ba01:7113
Link-local IPv6 Address . . . . . :fe80::5c7c:f9f1:5e81:d56%10
IPv4 Address. . . . . . . . . . . : 157.59.40.103
Subnet Mask . . . . . . . . . . . :255.255.248.0
Default Gateway . . . . . . . . . :fe80::207:dff:fee6:a400%10
157.59.40.1
……
…….
=====================================================
SourceMachine:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Net;
namespace Connection
{
class Program
{
static void Main(string[]args)
{
try
{
SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
List<IPAddress> IPs = newList<IPAddress>();
IPs.Add(IPAddress.Parse("10.80.225.111"));
IPs.Add(IPAddress.Parse("157.55.69.198"));
IPAddresssrcIP = IPs[0];
IPAddressdestIP = IPs[1];
//youcan use bind() to indentifyy a special port you want
IPEndPointsrcIPPort = new IPEndPoint(srcIP,4686);
//Bind method need a Endpoint object, but Endpoint is abstract class, so here weprovided IPEndPoint object which inherited form Endpoint.
Client.Bind(srcIPPort);
stringrequest = "GET / HTTP/1.1\r\n" +
"Host:"+ destIP + "\r\n" +
"Connection:Keep-Alive\r\n" +
"Keepalivetime:30\r\n" +
"Keepaliveinterval:15\r\n" +
"Keep-Alive:timeout=600\r\n\r\n";
/*
Providedestination IP and port, if there is not any service is listening in the portyour provided, an error will be returned like
"Noconnection could be made because the target machine actively refused it127.0.0.1:8000". If this happens always, it literally means that
* themachine exists but that it has no services listening on the specified port, orthere is a firewall stopping you. You can develop a simple
* websiteon port 80, or you can also write a port listen program to listen the port youwant to send data package to.
*/
Client.Connect(destIP, 13000);
Byte[]bytesSent = Encoding.ASCII.GetBytes(request.ToString());
Byte[]bytesReceived = new Byte[1024];
Client.Send(bytesSent,bytesSent.Length, 0);
intbytes = 0;
bytes =Client.Receive(bytesReceived, bytesReceived.Length, 0);
Console.Write("Returned byte size:" + bytes + "\r\n");
stringstrFromServer = "";
strFromServer = Encoding.ASCII.GetString(bytesReceived, 0, bytes);
Console.WriteLine("Returned context from server(or call Liste por) isas follwing:\r\n" + strFromServer);
Console.ReadLine();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
}
}
Destination Machine:<这里使用TCPClient,TCPListerner, 当然我们也可以利用socket类的方法去监听>(这个程序应该运行在在远程目的机器上面)
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
class MyTcpListener
{
public static void Main()
{
try
{
// Setthe TcpListener on port 13000.
Int32port = 13000;
IPAddresslocalAddr = IPAddress.Parse("157.55.69.198");
//TcpListener server = new TcpListener(port);
TcpListener server = new TcpListener(localAddr,port);
// Startlistening for client requests.
server.Start();
// Bufferfor reading data
Byte[]bytes = new Byte[256];
Stringdata = null;
// Enterthe listening loop.
while(true)
{
Console.Write("Waiting for a connection... ");
//Perform a blocking call to accept requests.
//You could also user server.AcceptSocket() here.
TcpClientclient = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
//Get a stream object for reading and writing
NetworkStream stream =client.GetStream();
inti;
//Loop to receive all the data sent by the client.
while((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate databytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received:{0}", data));
//Process the data sent by the client.
data = data.ToUpper();
byte[]msg = System.Text.Encoding.ASCII.GetBytes(data);
//Send back a response.
stream.Write(msg, 0,msg.Length);
Console.WriteLine(String.Format("Sent:{0}", data));
}
//Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
}