C
[윈도우 소켓프로그래밍] C 학생정보찾기 확장
돌맹96
2024. 6. 10. 21:37
728x90
반응형
이전 프로젝트에서 UI도 추가하고 몇가지 기능을 추가했다.
이름과 나이 국적 중 하나를 입력하면 전체값을 주게끔 만들었다.
Server 코드다.
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <process.h>
#include <windows.h>
#include <string.h>
#include <ws2tcpip.h> // for inet_pton
#pragma comment(lib, "ws2_32.lib")
#define BUF_SIZE 100
#define MAX_CLNT 256
#define STD_MAX_NUM 100
#define WHITE 15
#define YELLOW 6
#define BLUE 9
typedef struct student {
char name[30];
int age;
char nation[4];
char depart[3];
} STUDENT;
void setStudentData(FILE* fp);
unsigned WINAPI HandleClient(void* arg);
void SendMsg(char* msg, int len);
int clientCount = 0;
SOCKET clientSocks[MAX_CLNT];
HANDLE hMutex;
STUDENT students[STD_MAX_NUM];
int std_cnt = 0;
int main(int argc, char* argv[]) {
FILE* fpin;
WSADATA wsaData;
SOCKET serverSock, clientSock;
SOCKADDR_IN serverAddr, clientAddr;
int clientAddrSize;
HANDLE hThread;
int portNum;
if (fopen_s(&fpin, "students.txt", "r") != 0) {
printf("File open error...\n");
exit(-1);
}
setStudentData(fpin);
printf("Server : Set Server Port number (Please use integer number between 49152 to 65535) : ");
scanf_s("%d", &portNum);
WSAStartup(MAKEWORD(2, 2), &wsaData);
hMutex = CreateMutex(NULL, FALSE, NULL);
if (hMutex == NULL) {
printf("Mutex creation failed\n");
exit(-1);
}
serverSock = socket(PF_INET, SOCK_STREAM, 0);
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(portNum);
bind(serverSock, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
listen(serverSock, 5);
printf("Server : Ready to Client Connection\n");
while (1) {
clientAddrSize = sizeof(clientAddr);
clientSock = accept(serverSock, (SOCKADDR*)&clientAddr, &clientAddrSize);
WaitForSingleObject(hMutex, INFINITE);
clientSocks[clientCount++] = clientSock;
ReleaseMutex(hMutex);
char clientIP[INET_ADDRSTRLEN];
InetNtopA(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN);
hThread = (HANDLE)_beginthreadex(NULL, 0, HandleClient, (void*)&clientSock, 0, NULL);
printf("Connected Client IP : %s\n", clientIP);
}
closesocket(serverSock);
WSACleanup();
return 0;
}
unsigned WINAPI HandleClient(void* arg) {
SOCKET clientSock = *((SOCKET*)arg);
int strLen = 0, i;
char msg[BUF_SIZE] = "";
char result[BUF_SIZE] = "";
while (1) {
strLen = recv(clientSock, msg, BUF_SIZE - 1, 0);
msg[strLen] = '\0';
printf("Server : Received Message -> %s\n", msg);
if (!strcmp(msg, "q")) {
send(clientSock, "q", 1, 0);
break;
}
else if (!strncmp(msg, "LOGIN", 5)) {
// Implement login functionality
}
else if (!strncmp(msg, "FIND_ID", 7)) {
// Implement find ID functionality
}
else if (!strncmp(msg, "FIND_PW", 7)) {
// Implement find PW functionality
}
else if (!strncmp(msg, "SIGN_UP", 7)) {
// Implement sign up functionality
}
else {
// Default case, handle student info request
for (i = 0; i < std_cnt; i++) {
if ((strncmp(msg, "NAME ", 5) == 0 && strcmp(msg + 5, students[i].name) == 0) ||
(strncmp(msg, "AGE ", 4) == 0 && atoi(msg + 4) == students[i].age) ||
(strncmp(msg, "NATION ", 7) == 0 && strcmp(msg + 7, students[i].nation) == 0)) {
sprintf_s(result, BUF_SIZE, "%s,%d,%s,%s", students[i].name, students[i].age, students[i].nation, students[i].depart);
send(clientSock, result, strlen(result), 0);
printf("Send Result\n");
break;
}
}
if (i == std_cnt) {
sprintf_s(result, BUF_SIZE, "No Result");
send(clientSock, result, strlen(result), 0);
printf("Send No Result Message\n");
}
}
}
printf("client left the Server\n");
WaitForSingleObject(hMutex, INFINITE);
for (i = 0; i < clientCount; i++) {
if (clientSock == clientSocks[i]) {
while (i++ < clientCount - 1)
clientSocks[i] = clientSocks[i + 1];
break;
}
}
clientCount--;
ReleaseMutex(hMutex);
closesocket(clientSock);
return 0;
}
void setStudentData(FILE* fp) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
printf("Server : Initiation of Data Load \n");
while (!feof(fp)) {
fscanf_s(fp, "%s %d %s %s", students[std_cnt].name, (unsigned)_countof(students[std_cnt].name), &students[std_cnt].age, students[std_cnt].nation, (unsigned)_countof(students[std_cnt].nation), students[std_cnt].depart, (unsigned)_countof(students[std_cnt].depart));
std_cnt = std_cnt + 1;
}
printf("Server : End of Data Loading \n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
Client 코드다.
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h> // for inet_pton
#include <string.h>
#pragma comment(lib, "ws2_32.lib")
#define BUF_SIZE 100
void printMenu() {
printf("********** 검색시스템 **********\n");
printf("1. FIND BY NAME\n");
printf("2. FIND BY AGE\n");
printf("3. FIND BY NATION\n");
printf("0. EXIT\n");
printf("**************************\n");
printf("Choose an option: ");
}
int main() {
WSADATA wsaData;
SOCKET sock;
SOCKADDR_IN serv_addr;
char msg[BUF_SIZE];
int str_len;
int option;
char ip[INET_ADDRSTRLEN];
int port;
printf("Enter server IP: ");
scanf_s("%s", ip, (unsigned)_countof(ip));
printf("Enter server port: ");
scanf_s("%d", &port);
WSAStartup(MAKEWORD(2, 2), &wsaData);
sock = socket(PF_INET, SOCK_STREAM, 0);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
if (inet_pton(AF_INET, ip, &serv_addr.sin_addr) <= 0) {
printf("Invalid address/ Address not supported \n");
return -1;
}
serv_addr.sin_port = htons(port);
if (connect(sock, (SOCKADDR*)&serv_addr, sizeof(serv_addr)) == -1) {
perror("connect() error");
exit(1);
}
while (1) {
printMenu();
scanf_s("%d", &option);
getchar(); // Clear newline character from input buffer
memset(msg, 0, BUF_SIZE); // Initialize the msg buffer
switch (option) {
case 1:
printf("Enter name: ");
fgets(msg + 5, BUF_SIZE - 5, stdin); // Leave space for "NAME "
msg[strcspn(msg, "\n")] = 0; // Remove newline character
sprintf_s(msg, BUF_SIZE, "NAME %s", msg + 5);
send(sock, msg, strlen(msg), 0);
break;
case 2:
printf("Enter age: ");
fgets(msg + 4, BUF_SIZE - 4, stdin); // Leave space for "AGE "
msg[strcspn(msg, "\n")] = 0; // Remove newline character
sprintf_s(msg, BUF_SIZE, "AGE %s", msg + 4);
send(sock, msg, strlen(msg), 0);
break;
case 3:
printf("Enter nation: ");
fgets(msg + 7, BUF_SIZE - 7, stdin); // Leave space for "NATION "
msg[strcspn(msg, "\n")] = 0; // Remove newline character
sprintf_s(msg, BUF_SIZE, "NATION %s", msg + 7);
send(sock, msg, strlen(msg), 0);
break;
case 0:
send(sock, "q", 1, 0);
closesocket(sock);
WSACleanup();
return 0;
default:
printf("Invalid option. Please try again.\n");
continue;
}
str_len = recv(sock, msg, BUF_SIZE - 1, 0);
msg[str_len] = '\0';
printf("Server: %s\n", msg);
}
closesocket(sock);
WSACleanup();
return 0;
}
결과화면
728x90
반응형