강아지를 좋아하는 컴공생

[소켓프로그래밍] pthread_create() 매개변수 두 개이상 넘기기 본문

전공/네트워크 프로그래밍

[소켓프로그래밍] pthread_create() 매개변수 두 개이상 넘기기

정인하이 2020. 6. 19. 16:09

pthread_create 함수 형태

 

0을 반환시 성공, 0이 아닌값을 반환시 실패! 하는 pthread_create

pthread_create()의  arg에는 하나의 인자밖에 전달을 하지 못한다.

그러나! arg 부분을 통해 2개 이상의 인자를 전달하고 싶을 때 구조체를 이용하는 방법이 있다.

 

 

 

 

문제해결 개념 및 원리

개념 출처는 밑에!

 

 

이 개념이 필요했던 곳은 네트워크 프로그래밍 과제 중 소켓 프로그래밍 과제 중

서버 - 클라이언트 채팅 프로그램 작성시

서버입장에서는 어느 클라이언트에서 온 메시지인지 알 수 있는 방법이 

애초에 클라이언트가 보낼 메세지에 자신의 이름을 넣어 보내면 되겠다고 생각했다.

 

클라이언트는 서버에 접속을 할 때  자신의 이름을 입력해야하기 때문이다.

 

 

이름이 c2인 클라이언트

문제는 이 이름이 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 함수(외부함수)

send_msg 함수에서만 필요한 개념이므로, 받아온 arg에서 각 소켓&클라이언트이름을 분리한다.

소켓은 sock에, 클라이언트이름은 name에 받아온다.

 

클라이언트이름을 메시지와 함께 sprintf에서 합쳐버린다.

그 후 소켓(sock)을 통해 write함수로 서버에게 보내버리면 된다.

 

 

 

 

결과 확인

성공이다! 결과를 확인해보니... 서버에서 각 클라이언트 이름을 구분해서 인지하고 있더랬다!

(카운트 변수로는 절대 되지 않는 부분이다..이런 구조체 개념으로 해결하다니!)

 

 

서버는 client1이 보낸 메세지인지, clien2가 보낸 메세지인지 확인 가능한 상태가 되었다!

 

 

 

 

 

 

 

 

 

 

맨 위 사진 출처는 이 분 글을 참고했다!

http://blog.naver.com/PostView.nhn?blogId=duwnsrl&logNo=220414734910&parentCategoryNo=&categoryNo=32&viewDate=&isShowPopularPosts=false&from=postView