우분투 채팅프로그램 소스인데 한번만 봐주세요

오피스 업무, 개발 업무, 디자인 업무 등 다양한 분야에서의 리눅스 활용과 방법을 서로 이야기하고 질의하고 토의하는 곳

Moderator: Dry8r3aD

Post Reply
qkawnd12
Posts: 1
Joined: 2018/06/02 Sat 11:12 am

우분투 채팅프로그램 소스인데 한번만 봐주세요

Post by qkawnd12 » 2018/06/02 Sat 11:18 am

오픈소스로 만든 채팅프로그램인데
제가 채팅화면을 카톡처럼 만들고 싶어가지고
채팅 입력까지는 커서 제어해서 만들었는데
채팅이 오면 무조건 커서가 있는쪽으로 메세지가 오드라구요
그래서 입력받을때는 아래쪽에 커서두고 메세지 올때는 위쪽에 커서두고 싶은데
잘 안되네요 ㅠㅠㅠ 도와주세요
[code:3l2zjmch]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio_ext.h>
#include <pthread.h>
#include <termios.h>
#include <fcntl.h>
#include "getch.h"

int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;

tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

ch = getch();

tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);

if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}

return 0;
}

void gotoxy(int x, int y) {

printf("\033[%d;%df", y, x);

fflush(stdout);

}
int printMenu();// 메뉴 출력함수
void server(); // 서버
void client(); // 클라이언트 모드

void* recieve(void* p); // 메시지 읽는 쓰래드

void exitchat(char* str); // 종료 명령어 판별


char name[30];


int main(void)
{
system("clear"); //콘솔 지우기
int menu_select = printMenu(); // 메뉴 출력

if (menu_select == 1)
{
printf("server 실행 ");
server();

}
if (menu_select == 2)
{
printf("클라이언트 실행 ");
client();
}
else
gotoxy(1,24);
printf("종료합니다");

return 0;
}

void exitchat(char* str) // /exit를 입력 받으면 종료를 한다
{
if (strchr(str, '/exit'))
{
printf("5초후 접속을 종료합니다.\n ");
sleep(5); //5sec 대기
exit(1);
}
}

void* recieve(void* p) //메시지 읽기 쓰래드
{
char temp[100];
int str_len;
char result[150];

while (1)
{

str_len = read((int)p, temp, sizeof(temp));
if (str_len == 0)// 접속 끊김 확인
{
printf("접속이 끊겼습니다.");
exit(1);

}
else {


temp[str_len] = 0;

exitchat(temp);// /exit 명령어가 들어왔나 안들어왔나?

printf("%s ", temp);
// printf("%d ",(int)p);

strcpy(temp, ""); // 초기화
}
}


}
void server()
{
printf("사용할 닉네임 : ");
scanf("%s", name);//닉네임 입력받기
system("clear");

int serv_sock;
int clnt_sock;
int port;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;

socklen_t clnt_addr_size;
char message[1000];
char result[1200];
pthread_t r;
char temp[100];

void* s;

printf("사용할 포트 : ");
scanf("%d", &port);
printf("서버를 생성했습니다.\n");

serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (serv_sock == -1)
{
printf("Error발생\n 내용 : 소켓에러 ");
exit(1);
}

memset(&serv_addr, 0, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(port);

if (bind(serv_sock, (struct sockaddr*) & serv_addr, sizeof(serv_addr)) == -1)
{
printf("Error발생\n 내용 : 바인드 에러 "); exit(1);
}

if (listen(serv_sock, 5) == -1)
{
printf("Error발생\n 내용 : listen 에러"); exit(1);
}
printf("클라이언트 기다리는중........ \n");
clnt_addr_size = sizeof(clnt_addr);

clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);


if (clnt_sock == -1)
{
printf(" accept() error "); exit(1);
}
else
{
printf("클라이언트가 접속하였습니다.\n");
printf("--------------------------------\n");
printf("채팅을 시작합니다.\n/exit입력시 5초후 채팅프로그램이 종료됩니다.\n");
}
sleep(3);
system("clear");
int i, j;
int m[23][23] = { 3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,2,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,5,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7 };


for (i = 0; i < 23; i++) {
for (j = 0; j < 23; j++) {

switch (m[i][j]) {
case 0:
printf(" ");
break;
case 1:
printf("│");
break;
case 2:
printf("┐");
break;
case 3:
printf("┌");
break;
case 4:
printf("├");
break;
case 5:
printf("┤");
break;
case 8:
printf("──");
break;
case 6:
printf("└");
break;
case 7:
printf("┘");
break;
case 9:
printf("┬");
break;
case 10:
printf("┴");
break;

}
}
printf("\n");

}
__fpurge(stdin);



while (1)
{
gotoxy(2,2);
pthread_create(&r, NULL, recieve, (void*)clnt_sock);// 읽기 쓰래드 시작
__fpurge(stdin);
gotoxy(2,22);
gets(message); // 메시지 입력 받기
gotoxy(2,2);
sprintf(result, "%s: %s \n", name, message); //닉네임과 합치기
write(clnt_sock, result, strlen(result)); // 전송!
exitchat(result);

}

pthread_join(r, &s);

close(clnt_sock);

close(serv_sock);

}
void client()
{
printf("사용할 닉네임 : ");
scanf("%s", name);//닉네임 입력받기
system("clear");

int sock;
struct sockaddr_in serv_addr;
void* r; // 쓰레드 관련
pthread_t re; //쓰레드 관련
char message[1000];
int str_len;

char ip[16];
int port; //포트


printf("ip주소 : ");
scanf("%s", ip);

printf("포트번호 : ");

scanf("%d", &port);
printf("서버 접속중... \n");
printf("%s : %d 의 서버에 접속합니다 \n", ip, port);
printf("--------------------------------\n");
printf("채팅을 시작합니다.\n/exit입력시 5초후 채팅프로그램이 종료됩니다.\n");
sleep(3);
system("clear");
int i, j;

int l[23][23] = { 3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,2,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,5,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7 };


for (i = 0; i < 23; i++) {
for (j = 0; j < 23; j++) {

switch (l[i][j]) {
case 0:
printf(" ");
break;
case 1:
printf("│");
break;
case 2:
printf("┐");
break;
case 3:
printf("┌");
break;
case 4:
printf("├");
break;
case 5:
printf("┤");
break;
case 8:
printf("──");
break;
case 6:
printf("└");
break;
case 7:
printf("┘");
break;
case 9:
printf("┬");
break;
case 10:
printf("┴");
break;

}
}
printf("\n");

}
sock = socket(PF_INET, SOCK_STREAM, 0);


if (sock == -1)
{
printf("Error발생\n 내용 : 소켓에러");
exit(1);
}

memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(ip);
serv_addr.sin_port = htons(port);

// char temp[1000];
// char t[100]="";
//
char result[1200];//최종 메시지 변수

if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
{

printf("Error발생\n 내용 : 컨넥트 에러!!!!"); exit(1);
}
//__fpurge(stdin);


pthread_create(&re, NULL, recieve, (void*)sock); //read thread 생성

while (1)
{
gotoxy(2,2);
__fpurge(stdin);
gotoxy(2,22);
gets(message); //메시지 입력받음
gotoxy(2,2);
sprintf(result, " %s: %s \n", name, message); // 닉네임과 메시지 합치기
write(sock, result, strlen(result));
exitchat(result);
}
pthread_join(re, &r);
close(sock);
}

int printMenu()//메뉴출력
{
int select;

int key;
int i, j;
int x, y;
int s[23][23] = { 3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,2,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7 };


for (i = 0; i < 23; i++) {
for (j = 0; j < 23; j++) {

switch (s[i][j]) {
case 0:
printf(" ");
break;
case 1:
printf("│");
break;
case 2:
printf("┐");
break;
case 3:
printf("┌");
break;
case 4:
printf("├");
break;
case 5:
printf("┤");
break;
case 8:
printf("──");
break;
case 6:
printf("└");
break;
case 7:
printf("┘");
break;
case 9:
printf("┬");
break;
case 10:
printf("┴");
break;

}
}
printf("\n");

}
gotoxy(14, 4);
printf(" 메 인 메 뉴");
gotoxy(14, 8);
printf("1. 서버 실행");
gotoxy(14, 10);
printf("2. 클라이언트 실행");
gotoxy(14, 12);
printf("3. 종료");
gotoxy(14, 18);
printf("엔터를 눌러주세요!");
gotoxy(29, 8);
printf("◀");
x = 29;
y = 8;
while (1) { //무한 반복
key = getch();
if (key == 65) //위쪽으로 이동
{
if (y == 8) {
gotoxy(29,8);
printf(" ");
x = x - 5;
y = y + 4;
gotoxy(24,12);
printf("◀");
}
else if (y == 10) {
gotoxy(35,10);
printf(" ");
x = x - 6;
y = y - 2;
gotoxy(29,8);
printf("◀");
}
else if (y == 12) {
gotoxy(24,12);
printf(" ");
x = x + 11;
y = y - 2;
gotoxy(35,10);
printf("◀");
}
}
else if (key == 66) // 아래쪽으로 이동
{
if (y == 8) {
gotoxy(29,8);
printf(" ");
x = x + 6;
y = y + 2;
gotoxy(35,10);
printf("◀");
}
else if (y == 10) {
gotoxy(35,10);
printf(" ");
x = x - 11;
y = y + 2;
gotoxy(24,12);
printf("◀");
}
else if (y == 12) {
gotoxy(24,12);
x = x - 5;
y = y - 4;
printf(" ");
gotoxy(29,8);
printf("◀");
}

}
else if (key == 10) { //엔
if(y == 8){
system("clear");
server();

}
else if(y == 10){
system("clear");
client();
}
else if(y == 12){
system("clear");
gotoxy(1,24);
exit(1);
}
}
}
}[/code:3l2zjmch]

dks
Posts: 1
Joined: 2022/02/13 Sun 8:19 pm

Re: 우분투 채팅프로그램 소스인데 한번만 봐주세요

Post by dks » 2022/02/13 Sun 8:21 pm

오래된 포스트지만 ncurses 사용해보시는걸 추천드립니다.

Post Reply