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
| #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <windows.h> #include <string.h> #pragma comment(lib,"WS2_32.lib")
#pragma warning(disable:4996) #define BUF_SIZE 256 #define NAME_SIZE 30
#define SERVER_PORT "8888" #define DEFAULT_NAME "[DEFAULT]"
DWORD WINAPI send_msg(LPVOID lpParam); DWORD WINAPI recv_msg(LPVOID lpParam); void error_handling(const char* msg); SOCKET create_socket(const char* server_address); void connect_to_server(SOCKET sock, const char* server_address);
int main() { HANDLE hThread[2]; DWORD dwThreadId; WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 2); WSAStartup(sockVersion, &wsaData);
char name[NAME_SIZE]; printf("Input your Chat Name: "); scanf("%s", name); getchar();
char server_address[INET6_ADDRSTRLEN]; printf("Input server address (IPv4/IPv6 or domain name): "); scanf("%s", server_address);
SOCKET sock = create_socket(server_address); connect_to_server(sock, server_address);
hThread[0] = CreateThread(NULL, NULL, send_msg, (LPVOID)&sock, 0, &dwThreadId); hThread[1] = CreateThread(NULL, NULL, recv_msg, (LPVOID)&sock, 0, &dwThreadId);
WaitForMultipleObjects(2, hThread, TRUE, INFINITE); CloseHandle(hThread[0]); CloseHandle(hThread[1]); printf("Thread Over, Enter anything to over.\n"); getchar(); closesocket(sock); WSACleanup(); return 0; }
SOCKET create_socket(const char* server_address) { SOCKET sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) error_handling("Failed socket()"); return sock; }
void connect_to_server(SOCKET sock, const char* server_address) { struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(server_address, SERVER_PORT, &hints, &res) != 0) { error_handling("getaddrinfo failed"); }
for (struct addrinfo* p = res; p != NULL; p = p->ai_next) { if (connect(sock, p->ai_addr, (int)p->ai_addrlen) == SOCKET_ERROR) { closesocket(sock); sock = INVALID_SOCKET; continue; } break; }
freeaddrinfo(res); if (sock == INVALID_SOCKET) error_handling("Failed connect()"); printf("connect success\n"); }
DWORD WINAPI send_msg(LPVOID lpParam) { SOCKET sock = *((SOCKET*)lpParam); char name_msg[NAME_SIZE + BUF_SIZE]; char msg[BUF_SIZE];
while (1) { fgets(msg, BUF_SIZE, stdin); if (!strcmp(msg, "q\n") || !strcmp(msg, "Q\n")) { closesocket(sock); exit(0); } sprintf(name_msg, "[%s]: %s", name, msg); send(sock, name_msg, strlen(name_msg), 0); } return NULL; }
DWORD WINAPI recv_msg(LPVOID lpParam) { SOCKET sock = *((SOCKET*)lpParam); char name_msg[NAME_SIZE + BUF_SIZE]; int str_len;
while (1) { str_len = recv(sock, name_msg, NAME_SIZE + BUF_SIZE - 1, 0); if (str_len == -1) return -1; name_msg[str_len] = 0; fputs(name_msg, stdout); } return NULL; }
void error_handling(const char* msg) { printf("%s\n", msg); WSACleanup(); exit(1); }
|