---
# System prepended metadata

title: 網路程式設計 HW6
tags: [網路程式設計]

---

# 網路程式設計 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: `網路程式設計`