C言語マルチチャットルーム、Socketネットワークプログラミング


マルチチャットルーム、Windowsブラックウィンドウの2つのプログラム:serviceとclientはまずserviceを起動し、client入力IPを起動する必要があります.
実装手順サービス:
  • まずlisten
  • を作成
  • 接続要求
  • を再傍受する.
  • リクエストを受信すると、まず接続インスタンスをグローバルhash_に格納するmap中
  • 接続によって送信されたメッセージを傍受するスレッド
  • をさらに作成する.
  • サブスレッドメッセージを受信するとhash_map内のすべての接続グループメッセージ
  • クライアントがサーバに接続された後、サブスレッドを作成してサーバのメッセージを受信し、メインスレッド
  • client:
  • 接続サーバ
  • サブスレッドリスニングサーバを作成するメッセージ
  • メインスレッドループ待ちユーザ送信データ
  • サービスコード:
    #define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
    #define _CRT_SECURE_NO_WARNINGS
    #include
    #include
    #include
    #include
    #include
    #include
    #pragma comment(lib,"ws2_32.lib")
    #pragma comment(lib, "pthreadVC2.lib")
    #define max_conn_number 20
    using namespace std;
    
    typedef struct client {
    	int id;
    	char *name;
    	SOCKET socket;
    }Client;
    pair<int, Client> Pair;
    hash_map<int,Client> clients;
    const char *fenge = ":";
    const char *wellcome_str = "welcome to connect us,your first input is your name:\0";
    int wellcome_length = strlen(wellcome_str);
    int conn_number=0;
    
    void *client_run(void *args)
    {
    	Client *client = (Client *)args;
    	if (client->socket == INVALID_SOCKET)
    	{
    		printf("accept error !");
    		closesocket(client->socket);
    	}
    	send(client->socket, wellcome_str, wellcome_length, 0);
    	printf("       
    "
    ); // char name[1024]; int ret = recv(client->socket, name, 1023, 0); if (ret > 0) { client->name = name; name[ret] = 0x00;// } char recvData[1024]; char *sendData = (char *)malloc(1024 * sizeof(char)); while (1) { int ret = recv(client->socket, recvData, 1023, 0);// if (ret < 0)break;// memset(sendData, 0, 1024); recvData[ret] = 0x00;// sprintf(sendData, "%s%s", client->name, fenge);// sprintf(sendData, "%s%s", sendData, recvData);// for (auto iter = clients.begin(); iter != clients.end(); ++iter) {// if (iter->first == client->id)continue; send(iter->second.socket, sendData, strlen(sendData), 0); } } clients.erase(client->id); conn_number--; closesocket(client->socket); printf("
    "
    ); return NULL; } void findIP(char *ip, int size) { WORD v = MAKEWORD(1, 1); WSADATA wsaData; WSAStartup(v, &wsaData); // struct hostent *phostinfo = gethostbyname(""); char *p = inet_ntoa(*((struct in_addr *)(*phostinfo->h_addr_list))); strncpy(ip, p, size - 1); ip[size - 1] = '\0'; WSACleanup(); } int main(int argc, char* argv[]) { // WSA WORD sockVersion = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(sockVersion, &wsaData) != 0)return -1; // SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// , , if (slisten == INVALID_SOCKET) { printf("socket error !"); WSACleanup(); return -2; } printf(" !
    "
    ); char ip[20] = { 0 }; findIP(ip, sizeof(ip)); // IP sockaddr_in addr; addr.sin_family = AF_INET;// addr.sin_port = htons(8888);// addr.sin_addr.S_un.S_addr = inet_addr(ip); int r = bind(slisten, (LPSOCKADDR)&addr, sizeof(addr)); if (r == SOCKET_ERROR) { printf("bind error !"); closesocket(slisten); return -3; } printf(" !IP :%s。
    "
    ,ip); if (listen(slisten, 10) == SOCKET_ERROR) { printf("listen error !"); return -4; } // int i = 0;//socket , ID Client *client; pthread_t *thread; SOCKADDR remote_addr; int remote_addr_rlen=sizeof(remote_addr); while (conn_number<=max_conn_number) { client = (Client *)malloc(sizeof(Client)); thread= (pthread_t *)malloc(sizeof(pthread_t)); printf(" ...
    "
    ); client->socket = accept(slisten, &remote_addr, &remote_addr_rlen);// if (client->socket < 0) { free(client); printf("
    "
    ); continue; } client->id = i; clients[i] = *client;// hash_map printf(" ,
    "
    ); conn_number++; pthread_create(thread, NULL, client_run, &clients[i]); i++; } closesocket(slisten); WSACleanup(); return 0; }

    クライアントコード:
    #define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
    #define _CRT_SECURE_NO_WARNINGS
    #include
    #include
    #include 
    #include
    #include
    #include
    #include
    #pragma comment(lib,"ws2_32.lib")
    #pragma comment(lib, "pthreadVC2.lib")
    void *receive_message(void *args)
    {
    	SOCKET *sClient = (SOCKET *)args;
    	char *recvData = (char *)malloc(1024 * sizeof(char));
    	recvData[1023]='\0';
    	int ret;
    	while(1)
    	{
    		ret = recv(*sClient, recvData, 1023, 0);
    		if (ret < 0)break;
    		recvData[ret] = 0x00;//     
    		printf("%s
    "
    , recvData); } free(recvData); closesocket(*sClient); return NULL; } int main(int argc, char* argv[]) { WORD sockVersion = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(sockVersion, &wsaData) != 0)return -1; printf(" WSA !
    "
    ); SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// , , if (sClient == INVALID_SOCKET) { printf("socket error !"); WSACleanup(); return -2; } char server_ip[20] = { 0 }; printf(" ! IP:
    "
    ); scanf("%s", &server_ip); // sockaddr_in addr; addr.sin_family = AF_INET;// addr.sin_port = htons(8888);// addr.sin_addr.S_un.S_addr = inet_addr(server_ip); if (connect(sClient, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { printf("connect error !"); closesocket(sClient); return -3; } printf(" (%s) !
    "
    ,server_ip); pthread_t thread; pthread_create(&thread, NULL, receive_message, (void *)&sClient);// , char *sendData = (char *)malloc(1024 * sizeof(char));; sendData[1023] = '\0'; while (true) { memset(sendData, 0, 1024); scanf("%s", sendData); if (sendData == "quit\0")break; send(sClient, sendData, strlen(sendData), NULL); } free(sendData); closesocket(sClient); WSACleanup(); return 0; }