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 |