본문 바로가기

C#/공부

C# 실력 늘리기 4일차

113~114. 쓰레드와 Wait( ), PulseAll( ) 메서드, Monitor: 필요한 자원이 준비될 때까지 쓰레드 작업을 지연해 보자.

 

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(String[] args)
        {
            Plate plate = new Plate();
            Cake cake = new Cake(plate);
            Eat eat = new Eat(plate);

            cake.start("maker");
            eat.start("eater");
 
        }
    }
    public class Cake
    {
        private Plate plate;
        private string name;
        Thread makeThread;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public Cake(Plate plate)
        {
            this.plate = plate;
        }
        public void run()
        {
            for (int i = 0; i < 50; i++)
            {
                Console.Write(name + ": ");
                plate.make();
            }
            Console.WriteLine(name + ": 빵을 다 만들었으니 쉬자.");
        }
        public void start(string name)
        {
            this.name = name;
            makeThread = new Thread(new ThreadStart(run));
            makeThread.Name = name;
            makeThread.Start();
        }
    }
    public class Eat
    {
        private Plate plate;
        private string name;
        Thread makeThread;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public Eat(Plate plate)
        {
            this.plate = plate;
        }
        public void run()
        {
            for (int i = 0; i < 50; i++)
            {
                Console.Write(name + ": ");
                plate.eat();
            }
            Console.WriteLine(name + ": 빵을 다 먹었으니 쉬자.");
        }
        public void start(string name)
        {
            this.name = name;
            makeThread = new Thread(new ThreadStart(run));
            makeThread.Name = name;
            makeThread.Start();
        }
    }
    public class Plate
    {
        private int count = 0;
        object o = new object();
        public void make()
        {
            Monitor.Enter(o);
            {
                if (count >= 10)
                {
                    try
                    {
                        Console.WriteLine("빵이 남는다. 기다리자");
                        Monitor.Wait(o);
                    }
                    catch (Exception) { }
                }
                count++;
                Console.WriteLine("빵을 1개 더 만듬. 총 " + count + "개");
                Monitor.PulseAll(o);
                Monitor.Exit(o);
            }
        }
        public void eat()
        {
            Monitor.Enter(o);
            {
                if (count < 1)
                {
                    try
                    {
                        Console.WriteLine("빵이 모자라 기다림.");
                        Monitor.Wait(o);
                    }
                    catch (Exception) { }
                }
                count--;
                Console.WriteLine("빵을 1개 먹음. 총 " + count + "개");
                Monitor.PulseAll(o);
                Monitor.Exit(o);
            }
        }
    }
}

 

 

 

121. 웹 화면의  HTML 읽어오기: 웹 사이트에서 웹 화면의 HTML을 읽어오자.

 

이 블로그의 C# 카테고리 URL과 C# 실력 늘리기 1일차의 피라미드 계단 이미지 주소를 사용했다.

 

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;
using System.Net;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(String[] args)
        {
            WebReading wread = new WebReading();
            string url = "https://ggaebap.tistory.com/category/C%23";
            string str = wread.WebRead(url);
            Console.WriteLine(str);
            string topic = "https://blog.kakaocdn.net/dn/QkdXC/btrHIXUP8oq/QXg7wgB4qxuQMnxpBK42n0/img.png";
            wread.DownloadString(topic,"E:/images/test121.jpg");
        }
    }
    public class WebReading
    {
        public string WebRead(string url){
            WebClient web = new WebClient();
            string str="";
            using(Stream stream=web.OpenRead(url)){
                using(StreamReader sr=new StreamReader(stream)){
                    str=sr.ReadToEnd();
                }
            }
            return str;
        }
        public string DownloadString(string url)
        {
            WebClient web = new WebClient();
            string str = web.DownloadString(url);
            return str;
        }
        public void DownloadString(string url, string fname)
        {
            WebClient web = new WebClient();
            web.DownloadFile(url, fname);
        }
    }
}

 

HTML이 너무 길어 일부만 캡쳐함

 

 

다운로드 경로에 저장된 피라미드 계단 이미지

 

 

 

122~123. 웹에서 이미지 읽어오기, 읽어온 이미지 저장하기: 웹 화면에서 이미지를 읽어와서 저장하자.

 

122번에서 웹에서 비트맵으로 바로 읽어오는 메소드를 만들어놓고, 123번에선 웹을 읽어서 스트림을 만든 후 비트맵으로 변환해놨길래 그냥 122번에서 만들어둔 메소드를 사용했다. (사실 다운로드도 121번의 메소드를 사용하는게 훨씬 편하다)

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Drawing.Imaging;
using System.IO;

namespace Webdownlaod
{
    public partial class Form1 : Form
    {
        WebFile wf;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            wf = new WebFile();
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            string url = txtRead.Text;
            try
            {
                pictureBox1.Image = wf.DownloadBitmap(url);
            }
            catch (Exception) { MessageBox.Show("이미지를 읽어오는데 실패했습니다."); }
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            string url = txtRead.Text;
            string fname = txtSave.Text;
            try
            {
                Bitmap bit = wf.DownloadBitmap(url);
                MessageBox.Show(bit.Size.ToString());
                wf.SaveMemoryStream(bit, fname);
                MessageBox.Show("이미지 저장에 성공했습니다.");
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }
        public class WebFile
        {
            public Bitmap DownloadBitmap(string url)
            {
                WebClient web = new WebClient();
                byte[] downs = web.DownloadData(url);
                Bitmap bit = null;
                using (MemoryStream ms = new MemoryStream(downs))
                {
                    bit = new Bitmap(ms);
                }
                return bit;
            }
            public void SaveMemoryStream(Bitmap bit, string fname)
            {
                MemoryStream ms = new MemoryStream();
                bit.Save(ms, ImageFormat.Bmp);
                using (FileStream outStream = File.OpenWrite(fname))
                {
                    ms.WriteTo(outStream);
                    outStream.Close();
                }
            }
        }
    }
}

 

C# 실력 늘리기 3일차의 지뢰게임 이미지를 다운받아 보자.

 

 

다운로드 경로에 저장된 지뢰게임 이미지

 

 

 

124~127. 에코(Echo) 서버 만들기: 클라이언트에서 서버에 보낸 메세지를 다시 클라이언트로 보내자.

 

Client: IP를 localhost로 수정

 

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(String[] args)
        {
            Client client = new Client();
            client.Echo();
        }
        public class Client
        {
            public const int PORT = 5555;
            public const string IP = "localhost";
            public void Echo()
            {
                NetworkStream ns = null;
                StreamReader sr = null;
                StreamWriter sw = null;
                TcpClient client = null;
                try
                {
                    client = new TcpClient(IP, PORT);
                    ns = client.GetStream();
                    sr = new StreamReader(ns, Encoding.Default);
                    sw = new StreamWriter(ns, Encoding.Default);
                    string s = string.Empty;
                    Console.WriteLine("입력하세요");
                    while ((s = Console.ReadLine()) != null)
                    {
                        sw.WriteLine(s);
                        sw.Flush();
                        string message = sr.ReadLine();
                        Console.WriteLine(message);
                    }
                }
                catch (Exception ee) { System.Console.WriteLine(ee.Message); }
                finally
                {
                    sw.Close();
                    sr.Close();
                    client.Close();
                }
            }
        }
    }
}

 

Server: 자꾸 방화벽에 막혀서 Listener의 IP를 IPAdress.Any로 수정

 

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Server server = new Server();
            server.Echo();
        }
        public class Server
        {
            public const int PORT = 5555;
            public void Echo()
            {
                TcpListener listener = null;
                NetworkStream ns = null;
                StreamReader sr = null;
                StreamWriter sw = null;
                TcpClient client = null;
                try
                {
                    //IPAddress address = Dns.GetHostEntry("").AddressList[0];
                    //listener = new TcpListener(address, PORT);
                    listener = new TcpListener(IPAddress.Any, PORT);
                    listener.Start();
                    Console.WriteLine("server 1~~ready");
                    while (true)
                    {
                        Console.WriteLine("server 2~~ready");
                        client = listener.AcceptTcpClient();
                        Console.WriteLine("server 3~~Accept");
                        ns = client.GetStream();
                        sr = new StreamReader(ns, Encoding.Default);
                        sw = new StreamWriter(ns, Encoding.Default);
                        while (true)
                        {
                            string message = sr.ReadLine();
                            Console.WriteLine(message);
                            sw.WriteLine("[server: " + message + "]");
                            sw.Flush();
                        }
                    }
                }
                catch (Exception ee) { System.Console.WriteLine(ee.Message); }
                finally
                {
                    if (sw != null) sw.Close();
                    if (sr != null) sr.Close();
                    if (client != null) client.Close();
                }
            }
        }
    }
}

 

위쪽 cmd가 서버, 아래쪽 cmd가 클라이언트

 

'C# > 공부' 카테고리의 다른 글

C# 실력 늘리기 6일차  (0) 2022.07.26
C# 실력 늘리기 5일차  (0) 2022.07.25
C# 실력 늘리기 3일차  (0) 2022.07.21
C# 실력 늘리기 2일차  (0) 2022.07.20
C# 실력 늘리기 1일차  (0) 2022.07.19