# 網路程式設計 HW6 * 本週投影片提到的聊天室延伸功能有: - [x] 1. 三人交談 - [x] 2. 不雅字馬掉 (Ex: FxxK ) - [x] 3. 當有人說bye,結束此聊天室 - [ ] 4. 語句翻譯 - [x] 5. client設定發言者名後,將來對話顯示發言者 - [ ] 6. 當有人說bye,結束此聊天室 - [ ] 7. 二間聊天室 ## 1. 請任選以上二項聊天室延伸功能,實作一個聊天室系統。 * CODE * Server ```c== // simple TCP chatroom server // v3: Not require take turn talking #include <stdio.h> #include <winsock.h> int main(){ SOCKET sd,clnt_sd0,clnt_sd1,clnt_sd2,clnt_sd3; WSADATA wsadata; struct sockaddr_in serv,clnt0,clnt1,clnt2,clnt3; int i,n; char str[100]; WSAStartup(0x101,&wsadata); sd = socket(AF_INET, SOCK_STREAM, 0); serv.sin_family = AF_INET; serv.sin_port = htons(1234); serv.sin_addr.s_addr = inet_addr("127.0.0.1"); bind(sd, (struct sockaddr *) &serv, sizeof(serv)); listen(sd,5); int clnt_len1=sizeof(clnt1); int clnt_len2=sizeof(clnt2); int clnt_len3=sizeof(clnt3); printf("Server waits.\n"); clnt_sd1 = accept(sd, (struct sockaddr *) &clnt1,&clnt_len1 ); printf("(1) 1 connection.\n"); clnt_sd2 = accept(sd, (struct sockaddr *) &clnt2,&clnt_len2 ); printf("(2) 2 connections.\n"); clnt_sd3 = accept(sd, (struct sockaddr *) &clnt3,&clnt_len3 ); printf("(3) 3 connections.\n"); int clnt_len0=sizeof(clnt0); while(1){ clnt_sd0 = accept(sd, (struct sockaddr *) &clnt0,&clnt_len0 ); n = recv(clnt_sd0,str, 100, 0); if (n <= 0 ) break; closesocket(clnt_sd0); printf("%s\n",str); send(clnt_sd1,str, strlen(str)+1,0); send(clnt_sd2,str, strlen(str)+1,0); send(clnt_sd3,str, strlen(str)+1,0); char *BYE=strstr(str," : bye"); if(BYE!=NULL) { printf("\nBYEEEEE\n"); break; } /* if((str[0]=='b' || str[0]=='B')&& (str[1]=='y' || str[1]=='Y') && (str[2]=='e' || str[2]=='E')) { printf("\nBYEEEEEEEE\n"); break; //closesocket(sd); } */ } closesocket(sd); closesocket(clnt_sd0); closesocket(clnt_sd1); closesocket(clnt_sd2); closesocket(clnt_sd3); WSACleanup(); system("pause"); } ``` * Input ```c== // simple TCP chat client(1) // v3: no take turn #include <stdio.h> #include <winsock.h> #include <string.h> #include <stdlib.h> /* #include <iostream> #include <sstream> using namespace std; */ char *string_concat(char *str1, char *str2) { // 計算所需的陣列長度 int length=strlen(str1)+strlen(str2)+1; // 產生新的陣列空間 char *result = (char*)malloc(sizeof(char) * length); // 複製第一個字串至新的陣列空間 strcpy(result, str1); // 串接第二個字串至新的陣列空間 strcat(result, str2); return result; } char *str_replace (char *source, char *find, char *rep){ // 搜尋文字的長度 int find_L=strlen(find); // 替換文字的長度 int rep_L=strlen(rep); // 結果文字的長度 int length=strlen(source)+1; // 定位偏移量 int gap=0; // 建立結果文字,並複製文字 char *result = (char*)malloc(sizeof(char) * length); strcpy(result, source); // 尚未被取代的字串 char *former=source; // 搜尋文字出現的起始位址指標 char *location= strstr(former, find); // 漸進搜尋欲替換的文字 while(location!=NULL){ // 增加定位偏移量 gap+=(location - former); // 將結束符號定在搜尋到的位址上 result[gap]='\0'; // 計算新的長度 length+=(rep_L-find_L); // 變更記憶體空間 result = (char*)realloc(result, length * sizeof(char)); // 替換的文字串接在結果後面 strcat(result, rep); // 更新定位偏移量 gap+=rep_L; // 更新尚未被取代的字串的位址 former=location+find_L; // 將尚未被取代的文字串接在結果後面 strcat(result, former); // 搜尋文字出現的起始位址指標 location= strstr(former, find); } return result; } int main(){ SOCKET sd; WSADATA wsadata; struct sockaddr_in serv; int i,n; char str[100]="I love NP!"; char NAME[100]=""; char SEND[100]=""; WSAStartup(0x101,&wsadata); serv.sin_family = AF_INET; serv.sin_port = htons(1234); serv.sin_addr.s_addr = inet_addr("127.0.0.1"); printf("Enter your name : "); gets(NAME); while(1){ sd = socket(AF_INET, SOCK_STREAM, 0); printf("Input:"); gets(str); char *name=NAME; name=string_concat(name," : "); char* str2=str_replace(str,"fuck","fxxk"); char *SEND=string_concat(name,str2); connect(sd, (struct sockaddr *) &serv,sizeof(serv) ); send(sd,SEND,strlen(SEND)+1,0); printf("%s\n",SEND); //closesocket(sd); } WSACleanup(); } ``` * viewer ```c== // simple TCP chat client viewwer // v3: two client chat through server #include <stdio.h> #include <winsock.h> int main(){ SOCKET sd; WSADATA wsadata; struct sockaddr_in serv; int i,n; char str[100]="I love NP!"; WSAStartup(0x101,&wsadata); sd = socket(AF_INET, SOCK_STREAM, 0); serv.sin_family = AF_INET; serv.sin_port = htons(1234); serv.sin_addr.s_addr = inet_addr("127.0.0.1"); connect(sd, (struct sockaddr *) &serv,sizeof(serv) ); printf("Connect to server.\n"); while(1){ memset(str,0,100); n = recv(sd,str, 100, 0); if (n <=0) break; printf("%s\n",str); } closesocket(sd); WSACleanup(); system("pause"); } ``` * 執行結果 ![](https://i.imgur.com/XfNMDCj.png) ## 2. 本週心得 * 請寫下對於本週影片教學和程式作業的適應程度。 本次是目前為止覺得最有趣的作業。 原本想要改用C++寫,一開始執行的很順利,後來突然跳出下圖 ![](https://i.imgur.com/hX3IKIC.png) 跟室友討論後,發現他們也有人有這問題,只好改用C寫了。 ###### tags: `網路程式設計`