111,093
社区成员




服务端
class Program
{
public static void Main(string[] arg)
{
IPAddress ip = IPAddress.Parse("192.168.0.103");
int port = 5555;
List<Socket> ReadSock = new List<Socket>();
List<Socket> ErrorSock = new List<Socket>();
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ReadSock.Add(server);
Dictionary<Socket, SockData> ClientRecvFile = new Dictionary<Socket, SockData>();
server.Bind(new IPEndPoint(ip, port));
server.Listen(10);
while (true)
{
List<Socket> rs = new List<Socket>(ReadSock);
List<Socket> es = new List<Socket>(ErrorSock);
Socket.Select(rs, null, es, -1);
foreach (Socket sk in rs)
{
if (sk == server)
{
AcceptSock(ReadSock, ErrorSock, sk, ClientRecvFile);
continue;
}
if (sk.Available == 0)
{
CloseSock(ReadSock, ErrorSock, sk, ClientRecvFile);
continue;
}
ReceiveFile(sk, ClientRecvFile);
}
foreach (Socket sk in es)
CloseSock(ReadSock, ErrorSock, sk, ClientRecvFile);
}
}
static void AcceptSock(List<Socket> readsock, List<Socket> errorsock,
Socket server, Dictionary<Socket,SockData> clientfs)
{
Socket client = server.Accept();
readsock.Add(client);
errorsock.Add(client);
SockData sd = new SockData();
sd.DataRecvLen = 4;
sd.Buffer = new byte[4096];
clientfs.Add(client, sd);
Console.WriteLine("{0}建立连接", client.RemoteEndPoint);
}
static void ReceiveFile(Socket client, Dictionary<Socket,SockData> clientfs)
{
SockData sd = clientfs[client];
if (sd.SockFile == null)
{
ReceiveData(client, sd);
return;
}
int len = client.Receive(sd.Buffer);
sd.SockFile.Write(sd.Buffer, 0, len);
sd.FileRecvLen += len;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write("{0:P}", (double)sd.FileRecvLen / sd.FileLen);
if (sd.FileRecvLen < sd.FileLen)
return;
sd.Clear();
Console.WriteLine();
}
static void ReceiveData(Socket client, SockData sd)
{
int len2 = client.Receive(sd.Buffer, sd.OffSet, sd.DataRecvLen, SocketFlags.None);
if (len2 != sd.DataRecvLen)
{
sd.SetBuffer(sd.OffSet + len2, sd.DataRecvLen - len2);
return;
}
if (sd.OffSet < 4)
{
int datalen = BitConverter.ToInt32(sd.Buffer, 0);
if (datalen <= 4)
{
sd.SetBuffer(0, 4);
return;
}
sd.SetBuffer(4, datalen - 4);
return;
}
DoSomething(client, sd);
}
static void DoSomething(Socket client, SockData sd)
{
string filename = sd.SetFileInfo();
Console.WriteLine("开始接收文件{0}", filename);
}
static void CloseSock(List<Socket> readsock, List<Socket> errorsock,
Socket client, Dictionary<Socket, SockData> clientfs)
{
Console.WriteLine("{0}断开连接", client.RemoteEndPoint);
client.Shutdown(SocketShutdown.Both);
client.Close();
readsock.Remove(client);
errorsock.Remove(client);
clientfs[client].Dispose();
clientfs.Remove(client);
}
}
class SockData : IDisposable
{
public int OffSet { get; set; }
public int DataRecvLen { get; set; }
public int FileLen { get; set; }
public int FileRecvLen { get; set; }
public FileStream SockFile { get; set; }
public byte[] Buffer { get; set; }
public void SetBuffer(int offset, int len)
{
OffSet = offset;
DataRecvLen = len;
}
public string SetFileInfo()
{
FileLen = BitConverter.ToInt32(Buffer, 4);
int filenamelen = BitConverter.ToInt32(Buffer, 8);
string filename = Encoding.Unicode.GetString(Buffer, 12, filenamelen);
SockFile = new FileStream(filename, FileMode.Create, FileAccess.Write);
return filename;
}
public void Clear()
{
OffSet = 0;
DataRecvLen = 4;
FileLen = 0;
FileRecvLen = 0;
if (SockFile == null)
return;
SockFile.Close();
SockFile = null;
}
public void Dispose()
{
if (SockFile != null)
SockFile.Close();
GC.SuppressFinalize(this);
}
~SockData()
{
if (SockFile != null)
SockFile.Close();
}
}
客户端
class Program
{
static IPAddress ip = IPAddress.Parse("192.168.0.103");
static int port = 5555;
static Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
[STAThread]
static void Main(string[] args)
{
SocketAsyncEventArgs sendarg = new SocketAsyncEventArgs();
sendarg.Completed += new EventHandler<SocketAsyncEventArgs>(sendarg_Completed);
Console.WriteLine("正在连接");
while (true)
{
try { client.Connect(ip, port); Console.WriteLine("连接完毕"); break; }
catch { Console.WriteLine("连接失败,正在重试"); Thread.Sleep(1000); }
}
ThreadPool.QueueUserWorkItem(Receive);
while (true)
{
Console.WriteLine("回车选择要传输的文件");
Console.ReadLine();
OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() != DialogResult.OK)
continue;
string pathname = fd.FileName;
string filename = fd.SafeFileName;
SendFile(client, pathname, filename, sendarg);
}
}
static void SendFile(Socket client, string pathname, string filename, SocketAsyncEventArgs sendarg)
{
List<SendPacketsElement> list = new List<SendPacketsElement>();
byte[] header = new byte[12 + filename.Length * 2];
FileStream fs = new FileStream(pathname, FileMode.Open, FileAccess.Read);
int filelen = (int)fs.Length;
fs.Close();
GCHandle handle = GCHandle.Alloc(header);
IntPtr p = Marshal.UnsafeAddrOfPinnedArrayElement(header, 0);
Marshal.WriteInt32(p, header.Length);
Marshal.WriteInt32(p + 4, filelen);
Marshal.WriteInt32(p + 8, filename.Length * 2);
handle.Free();
Encoding.Unicode.GetBytes(filename, 0, filename.Length, header, 12);
list.Add(new SendPacketsElement(header));
list.Add(new SendPacketsElement(pathname));
sendarg.SendPacketsElements = list.ToArray();
client.SendPacketsAsync(sendarg);
}
static void sendarg_Completed(object sender, SocketAsyncEventArgs e)
{
Console.WriteLine("传输完毕");
}
static void Receive(object obj)
{
byte[] buffer = new byte[4096];
while (true)
{
if (!client.Connected)
{
Console.WriteLine("正在连接");
try { client.Connect(ip, port); Console.WriteLine("连接完毕"); }
catch { Console.WriteLine("连接失败,正在重试"); Thread.Sleep(1000); }
continue;
}
SocketError error;
int len = client.Receive(buffer, 0, buffer.Length, SocketFlags.None, out error);
if (len != 0 && error == SocketError.Success)
continue;
Console.WriteLine("连接断开");
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
}
}