using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Collections; using System.Threading; using System.Linq; public class UdpSrvrSample { private static int game_state = 0;//0-gra czeka na rozpoczecie 1- gra skonczona; private static int connected_hosts = 0;//licznik hostow private static int times_up = 0;//0-nie minelo jeszcze 10s private static Random random = new Random(); public static int sekretna = random.Next(0, 15); public static int time2; public static void Timer(string h2,string h1) { int id1 = Convert.ToInt32(h1, 2); int id2 = Convert.ToInt32(h2, 2); time2 = (((id1 + id2) * 99) % 100) + 30; while(time2!=0) { if (time2 >= 10) { Thread.Sleep(10000); time2 = time2 - 10; } else { Thread.Sleep(time2 * 1000); time2 = 0; game_state++;//timeout } times_up++; } } static byte [] ProtocolBuilder(string operation,string response,string idref,string dop="none")//buduje pakiet { int pom1 = 0, pom2 = 0, pom3 = 0, pom4 = 0; BitArray c = new BitArray(24); BitArray g = new BitArray(24); byte[] data = new byte[3]; for (int i=0;i5 && i<=9) { if (response[pom2] == '0') c[i] = false; else c[i] = true; pom2++; } if(i>9 && i<=17) { if (idref[pom3] == '0') c[i] = false; else c[i] = true; pom3++; } if (i > 17) { if(dop=="none") c[i] = false; else { if (dop[pom4] == '0') c[i] = false; else c[i] = true; pom4++; } } } for (int i = 0; i < c.Length; i++) { g[g.Length - i-1] = c[i]; } g.CopyTo(data, 0); Array.Reverse(data, 0, data.Length); return data; } public static string ToBin(int value, int len)//int do binarki { return (len > 1 ? ToBin(value >> 1, len - 1) : null) + "01"[value & 1]; } public static string[] DecodePacket(byte[] c)//funkcja odbiera pobrane inty i zamienia je na kod binarny { string h = ""; string [] a=new string[3]; for (int i = 0; i < c.Length;i++) { h=h+ ToBin(c[i], 8);//dopelnia do 8 bitow } for(int i=0;i 5 && i <= 9) a[1] = a[1] + h[i]; if (i > 9 && i <= 17) a[2] = a[2] + h[i]; } return a; } public static string RandomString(int length)// funckja losujaca id sesji { string liczba; if(connected_hosts==1) { int h = random.Next(0, 122); liczba = ToBin(h,8); } else { int h = random.Next(122, 254); liczba = ToBin(h, 8); } return liczba; } static byte [] TellAction(byte[] c,ref string h)//ustalanie akcji na podstawie pola operacji { byte[] bytes = new byte[3]; string[] packet = new string[3]; packet = DecodePacket(c); switch (packet[0]) { case "000000": { h = RandomString(8); bytes = ProtocolBuilder("100000", "0000", h); break; } case "010000": { string l = ToBin(sekretna, 4); if (l == packet[1]) { bytes = ProtocolBuilder("110000", "0000", h); game_state = 1; } else bytes = ProtocolBuilder("001000", "0000", h); break; } case "110100": { //connected_hosts--; //game_state = 1; break; } } return bytes; } public static void SecondChannel(int port, string h)//kanal w ktorym do serwer inicjuje komunikacje { IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port+10); UdpClient newsock = new UdpClient(ipep); IPEndPoint sender = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0); ReceivePacket(ref newsock, ref sender, ref h); while (true) { if(game_state == 1)// wysylanie pakietu informujacego o koncu gry { byte[] newArray = new byte[3]; if(time2==0) { newArray = ProtocolBuilder("111000", "0000", h);//timeout } else { newArray = ProtocolBuilder("111000", "1111", h);//liczba zostala zgadnieta } SendPacket(newsock, newArray, sender); } if(times_up==1 && game_state==0) { byte[] newArray = new byte[3]; string czas = ToBin(time2,10); string part1 = "", part2 = ""; for (int i = 0; i <= 3; i++) part1 = part1+czas[i]; for (int i = 4; i <10; i++) part2 = part2 + czas[i]; newArray = ProtocolBuilder("101000", part1, h, part2); SendPacket(newsock, newArray, sender); Console.WriteLine("Wysylam pakiet czasu"); times_up = 0; } } } public static void CallToChildThread(int port,ref string h) { int g=0; byte[] data = new byte[3]; string c = h; Thread thread3 = new Thread(() => SecondChannel(port, c)); IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port); UdpClient newsock = new UdpClient(ipep); IPEndPoint sender = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0); byte[] bytes = new byte[3]; data = ReceivePacket(ref newsock, ref sender, ref h); bytes=TellAction(data, ref h); SendPacket(newsock, bytes, sender); connected_hosts++; thread3.Start(); while (true) { if(g==0 && connected_hosts==2)//czeka na polaczenie obu hostow po czym wysyla informacje o rozpoczeciu rozgrywki { g = 1; byte[] newArray = new byte[3]; newArray = ProtocolBuilder("100100", "0000", h); SendPacket(newsock, newArray, sender); } if (g == 1 && connected_hosts == 2)//pobiera liczbe wyslana przez klienta i odsyla prawda/falsz { data = ReceivePacket(ref newsock, ref sender, ref h); bytes = TellAction(data, ref h); SendPacket(newsock, bytes, sender); } } } static void SendPacket(UdpClient klient,byte [] bytes,IPEndPoint sender)//wysyla dane po czym czeka na potwierdzenie { klient.Send(bytes, bytes.Length, sender); klient.Receive(ref sender); } static byte[] ReceivePacket(ref UdpClient klient,ref IPEndPoint sender,ref string h )//zapisuje wyslane dane i potwierdza ich odebranie { byte[] ACK = new byte[3]; byte[] data = new byte[3]; data = klient.Receive(ref sender); ACK= ProtocolBuilder("111111", "0000", h); klient.Send(ACK, ACK.Length, sender); return data; } public static void Main() { byte[] data = new byte[3]; string h1 = "00000000"; string h2 = "00000000"; Console.Write("Losowa liczba to: "); Console.Write(sekretna); Thread thread2 = new Thread(() => CallToChildThread(9050,ref h1));//po jednym watku dla kazdego klienta Thread thread3 = new Thread(() => CallToChildThread(9051,ref h2)); thread2.Start(); thread3.Start(); while(true)//zatrzymuje watek do momentu polaczenia dwoch klientow, niesamowicie oszczedne rozwiazanie { if (connected_hosts == 2) break; } Thread timer = new Thread(() => Timer( h1, h2)); timer.Start(); int a = Console.Read(); } }