일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 자료구조
- 네트워크 프로그래밍
- 채팅프로그램
- 소켓 프로그래밍
- Git
- 이진트리
- GitHub
- remove_if
- bind
- 연산자오버로딩
- operator==
- 과제5차
- 튜토리얼
- list
- 동빈나참고
- 난수중복제거
- C++
- 멀티스레드
- greater
- 이진노드
- 과제
- 상속
- 에러
- 노드
- 클라이언트
- c2678
- 함수객체
- BST
- 이진순회트리
- placeholder
- Today
- Total
강아지를 좋아하는 컴공생
[소켓프로그래밍] pthread_create() 매개변수 두 개이상 넘기기 본문
pthread_create 함수 형태
pthread_create()의 arg에는 하나의 인자밖에 전달을 하지 못한다.
그러나! arg 부분을 통해 2개 이상의 인자를 전달하고 싶을 때 구조체를 이용하는 방법이 있다.
문제해결 개념 및 원리
이 개념이 필요했던 곳은 네트워크 프로그래밍 과제 중 소켓 프로그래밍 과제 중
서버 - 클라이언트 채팅 프로그램 작성시
서버입장에서는 어느 클라이언트에서 온 메시지인지 알 수 있는 방법이
애초에 클라이언트가 보낼 메세지에 자신의 이름을 넣어 보내면 되겠다고 생각했다.
클라이언트는 서버에 접속을 할 때 자신의 이름을 입력해야하기 때문이다.
문제는 이 이름이 main의 argv[1]에 저장되어있다는 것이다(argv[0]는 아마 ./client 일껄...?)
그런데 이 argv[1]은 main함수 안에서만! 사용이 가능하다!
내가 만든 외부함수인 send_msg 함수와 recv_msg 함수에서는 쓸 수가 없는인자인것이다.
따라서 우리는 이 argv[1] 자체를 main함수에서 어떻게든 외부함수들에 전달을 해야한다.
해결방법
이 때 생각난 해결방법은 다음과 같다.
pthread_create 를 하면서 스레드를 생성할 때, send_msg 함수의 매개변수 부분인 arg 부분에 같이 전달하면 된다!
arg 부분에 두 개의 인자(소켓과 클라이언트명)를 저장한 구조체 변수를 넣어주는 것이다!
직접 구현을 해보겠다.
클라이언트가 자신의 이름을 서버에게 보낼 때만 필요한 개념이므로 client.c 파일 속에서 구현한 부분을 정리했다.
직접 구현
[client.c]
thread 라는 이름의 구조체변수와
thread.socket 에는 클라이언트의 소켓변수를,
thread.ip 에는 클라이언트 이름 c2를 저장한다. (argv[1]이 컴파일시 사용자가 입력했던 클라이언트 이름)
그리고, pthread_create 함수의 인자로 client_socket 대신 thread 구조체 변수를 전달한다.
send_msg 함수에서만 필요한 개념이므로, 받아온 arg에서 각 소켓&클라이언트이름을 분리한다.
소켓은 sock에, 클라이언트이름은 name에 받아온다.
클라이언트이름을 메시지와 함께 sprintf에서 합쳐버린다.
그 후 소켓(sock)을 통해 write함수로 서버에게 보내버리면 된다.
결과 확인
성공이다! 결과를 확인해보니... 서버에서 각 클라이언트 이름을 구분해서 인지하고 있더랬다!
(카운트 변수로는 절대 되지 않는 부분이다..이런 구조체 개념으로 해결하다니!)
서버는 client1이 보낸 메세지인지, clien2가 보낸 메세지인지 확인 가능한 상태가 되었다!
맨 위 사진 출처는 이 분 글을 참고했다!