이론
파이참에서 setting->ProjectInterpreter-> 초록색 + 에서 필요한것 install Package 가능
Pyqt5를 인스톨하여 파이참에서도 UI창 사용가능
파이썬이 서버일때의 장점 :라즈베리가 서버가 되면, 하드웨어들의 연동이 가능해진다.
실습
Ex1_Server.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | package ex1; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; //서버 코드: 클라이언트로부터 소켓의 연결 요청이 오면 accept()메서드가 호출이 되어서 Socket객체를 반환하고 //다중 소켓을 처리하기 위해서 ArrayList에 적재한다. //이때 ArrayList에 들어갈 소켓들은 스레드가 담당하게 되며, 접속한 클라이언트당 소켓이 각각 ArrayList에 들어가게 되는 구조이다. //Thread는 결국 각 소켓의 연결된 스트림을 담당하게 되고 서버는 이 스트림을 통해서 각각의 클라이언트에게 응답메세지를 전달하게 된다. public class Ex1_Server { private ServerSocket ss; private ArrayList<ServerThread> clist; private String reip; public Ex1_Server( int port) { //2. 생성자 초기화 //소켓생성, ServerThread를 저장할 ArrayList생성 try { ss= new ServerSocket(port); clist = new ArrayList<>(); System.out.println( "Start Server!" ); } catch (IOException ex) { ex.printStackTrace(); } } public void execute(){ //4.무한반복하면서 Socket의 accept() 접속을 대기한다. while ( true ){ try { Socket s = ss.accept(); //---------------------- //6.접속해온 클라이언트의 소켓을 ServerThread가 관리하도록 한명이 접속해 올때 마다 생성시켜두고 //이것을 Generic로 가지고 있는 ArrayList에 그 주소를 넣어서 소켓의 주소를 메모리영역에 참조하게 한다. // 스레드는 start한다. ServerThread ct = new ServerThread(s, this ); clist.add(ct); //ArrayList에 클라이언트를 담당할 스레드를 저장한다. ct.start(); // 스레드를 시작한다. System.out.println( "Current number of Clients :" +clist.size()); } catch (IOException ex) { ex.printStackTrace(); } } } public void sendMsg(String str1, String str2, String str3, String reip) { // str1/str2/str3/str4/str5 //서버를 제작할? 각 조에 맞는 프로토콜을 설계하기 바람 String str = "" ; if (str1.equals( "msg" )){ str = "msg/[" +reip+ "]" +str2+ "/" +str3; } else if (str1.equals( "enter" )){ //이런식으로... x/y/color등을 보낼 수 있다. str= "enter/" +str2+ "/" +str3; } //모든 유저에게 브로드캐스팅을 한다. //모든 유저는 for문을 사용해서 for (ServerThread c : clist){ c.getPw().println(str); } } public static void main(String[] args) { //1. 서버 시작을 위해서 port를 9999번으로 입력한 서버객체를 생성한다. Ex1_Server es = new Ex1_Server( 9999 ); //3. 생성된 Ex1_Server객체의 execute메서드를 호출한다. es.execute(); } } |
FXMLDocumentController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package javaclient0529; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.URL; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.control.Label; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.layout.StackPane; public class FXMLDocumentController implements Initializable { @FXML private TextField hostv, portv, userv,msgv; @FXML private TextArea chatmsgv; //StackPane 가져오기 @FXML private StackPane rootP; private ObservableList<Node> childs; private Node firstNode, secondNode; private Socket s; //사용자 이름 private String userName; private boolean flag; private String[] token; @Override public void initialize(URL url, ResourceBundle rb) { childs = rootP.getChildren(); firstNode = childs.get(childs.size() - 1 ); secondNode = childs.get(childs.size() - 2 ); } //첫번째 Pane에서 소켓으로 접속하는 버튼 @FXML private void connectButtonAction(ActionEvent event) { //SocketServerDemo.Ex1_Server에 접속하기 위해서 소켓을 연결한다. try { userName=userv.getText().trim(); s = new Socket(hostv.getText().trim(), Integer.parseInt(portv.getText().trim())); firstNode.setVisible( false ); firstNode.toBack(); secondNode.setVisible( true ); PrintWriter out = new PrintWriter(s.getOutputStream(), true ); //enter/user/null/null //msg/user/message/null //btn/user/value/null //통신규약을 가지고 서버로 전송한다. out.println( "enter/" +userName+ "/null/null" ); responseThread(); } catch (IOException ex) { } } private void responseThread() { Thread th = new Thread( new Runnable() { @Override public void run() { BufferedReader br = null ; try { br = new BufferedReader( new InputStreamReader(s.getInputStream())); while (!flag){ String msg = br.readLine(); Platform.runLater( new Runnable() { @Override public void run() { token = msg.split( "/" ); String message = "" ; if (token[ 0 ].equals( "enter" )){ message=token[ 1 ]+ " 님이 들어왔어요! \n" ; } else if (token[ 0 ].equals( "msg" )){ message= "[" +token[ 1 ]+ "]" +token[ 2 ]+ "\n" ; } chatmsgv.appendText(message); } }); } } catch (IOException ex) { ex.printStackTrace(); } finally { try { if (br != null ) br.close(); } catch (IOException ex) { ex.printStackTrace(); } } } }); th.setDaemon( true ); th.start(); } @FXML private void sendMessageAction(ActionEvent event) { String msg = msgv.getText().trim(); //msg/user/message/null StringBuffer msgBuf = new StringBuffer(); msgBuf.append( "msg/" ).append(userName).append( "/" ).append(msg).append( "/null" ); try { sendData(msgBuf.toString()); } catch (IOException ex) { ex.printStackTrace(); } } private void sendData(String data) throws IOException{ PrintWriter out = new PrintWriter( new BufferedOutputStream(s.getOutputStream()), true ); out.println(data); } @FXML private void exitButtonAction(ActionEvent event) { secondNode.setVisible( false ); secondNode.toBack(); firstNode.setVisible( true ); } // 두번째 버튼들.. red,blue,all ->Led값을 전송 //protocol형식으로 전송 @FXML private void redLedButtonAction(ActionEvent event) { } @FXML private void blueLedButtonAction(ActionEvent event) { } @FXML private void allLedButtonAction(ActionEvent event) { } } |
echoSocket0529.py
1 2 3 4 5 6 7 8 9 10 11 12 13 | #echoSocket0529.py import socket HOST = '192.168.0.115' PORT = 9999 def run(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST,PORT)) line = input ( 'Msg:' ) s.sendall(bytes(line + "\n" , 'ascii' )) resp = s.recv( 1024 ) print (resp.decode()) if __name__ = = '__main__' : run() |
echoSocketServer0529.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #echoSocketServer0529.py import socketserver import time HOST = "" PORT = 9999 class MyTcpHandler(socketserver.BaseRequestHandler): def handle( self ): print ( "[%s] connect" % self .client_address[ 0 ]) try : while True : self .data = self .request.recv( 1024 ) print ( "[%s]" % self .data.decode()) except Exception as e: print (e) def runServer(): print ( "Echo서버 시작" ) print ( "에코서버 중지는 ctrl+C" ) try : server = socketserver.TCPServer((HOST,PORT),MyTcpHandler) server.serve_forever() except KeyboardInterrupt: print ( "에코서버 종료" ) runServer() |
EchoSocketServerLed0529.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #EchoSocketServerLed0529.py import RPi.GPIO as GPIO from time import sleep import socketserver import time HOST = "" PORT = 9999 class MyTcpHandler(socketserver.BaseRequestHandler): def handle( self ): print ( "__init__" ) GPIO.setmode(GPIO.BCM) GPIO.setwarnings( False ) self .led_pin = 27 self .led_pin1 = 17 GPIO.setup( self .led_pin, GPIO.OUT) GPIO.setup( self .led_pin1, GPIO.OUT) print ( "[%s] connect" % self .client_address[ 0 ]) try : while True : self .data = self .request.recv( 1024 ) print ( "[%s]" % self .data.decode()) # bytes(line+"\n", 'ascii') toks = self .data.decode() t1 = toks.split( "/" ) print ( "Message Log=============================" ) print (t1[ 0 ]) print (t1[ 1 ]) print (t1[ 2 ]) if t1[ 0 ] = = "enter" or t1[ 0 ] = = "msg" : self .request.sendall( self .data) else : if t1[ 2 ] = = "red" : print ( "Red Led On" ) GPIO.output( self .led_pin, True ) GPIO.output( self .led_pin1, False ) self .request.sendall( "btn/null/RedLedOn/null \n" .encode()) sleep( 1 ) elif t1[ 2 ] = = "blue" : print ( "Blue Led On" ) GPIO.output( self .led_pin, False ) GPIO.output( self .led_pin1, True ) self .request.sendall( "btn/null/BlueLedOn/null \n" .encode()) sleep( 1 ) elif t1[ 2 ] = = "all" : GPIO.output( self .led_pin, False ) GPIO.output( self .led_pin1, False ) self .request.sendall( "btn/null/ALLLedOff/null \n" .encode()) # GPIO.cleanup() sleep( 1 ) except Exception as e: print (e) GPIO.cleanup() def runServer(): print ( "Echo서버 시작" ) print ( "에코서버 중지는 Ctrl+C" ) try : server = socketserver.TCPServer((HOST, PORT), MyTcpHandler) server.serve_forever() except KeyboardInterrupt: server.server_close() print ( "에코서버 종료" ) runServer() |
'학원수업 > 파이썬' 카테고리의 다른 글
학원 51일차 복습(5/31) (0) | 2018.05.31 |
---|---|
학원 50일차 복습(5/30) (0) | 2018.05.30 |
학원 48일차 복습(5/28) (0) | 2018.05.28 |
학원 45일차 복습(5/18) (0) | 2018.05.23 |
학원 44일차 복습(5/17) (0) | 2018.05.17 |