1. 程式人生 > >linux網路程式設計練習---聊天室(TCP/IP實現)

linux網路程式設計練習---聊天室(TCP/IP實現)

為了更深刻的鍛鍊認識TCP/IP協議,加強自己對Linux系統的網路程式設計部分的編寫程式碼能力,編寫基於控制檯的聊天視窗,用本機既當伺服器又當客戶端,先開啟一個shell,執行伺服器程式,然後再開啟一個shell視窗,執行客戶端程式,顯示連線成功,開始聊天吧。不知道為什麼上傳效果圖不成功,把圖放在相簿了。

/*客戶端*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define BUFFER_SIZE 256
#define PORT 4568
char recv_buff[BUFFER_SIZE];
char send_buff[BUFFER_SIZE];
int main(void)
{
    char write_flag=0;
    char read_flag=1;
    int sockfd;// 套結字
    struct sockaddr_in cli_addr;//伺服器的IPv4的套結字結構
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)//建立套結字
    {
        perror("socket");
        exit(1);
    }
    else
    {
        printf("creat client socket success id:%d\n",sockfd);
    }
    bzero(&cli_addr,sizeof(struct sockaddr_in));
    cli_addr.sin_family=AF_INET;
    cli_addr.sin_port=htons(PORT);
    cli_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    if(connect(sockfd,(struct sockaddr*)(&cli_addr),sizeof(struct sockaddr))<0)
    {
        perror("connect");
        exit(2);
    }
    else
    {
        printf("connect server success.\n");
    }
    memset(send_buff,0x00,sizeof(send_buff));
    memset(recv_buff,0x00,sizeof(send_buff));
   while(1)
    {
        if(strlen(send_buff)==0&&write_flag==1)//判斷髮送緩衝區是否為空
        {
            gets(send_buff);
            if(write(sockfd,send_buff,strlen(send_buff))<0)
            {
                perror("write");
                exit(3);
            }
            else
            {
                printf("Client:\n");
                printf("       %s\n",send_buff);
            }
            read_flag=1;
            write_flag=0;
            memset(recv_buff,0x00,strlen(recv_buff));
        }
       else if(strlen(recv_buff)==0&&read_flag==1)
        {

            if(read(sockfd,recv_buff,sizeof(recv_buff))<0)
            {
                perror("read");
                exit(4);
            }
            else if(strlen(recv_buff)>0)
            {
                printf("server:\n");
                printf("      : %s\n",recv_buff);
                memset(send_buff,0x00,strlen(send_buff));//接受到資料後清空傳送緩衝區
                write_flag=1;
                read_flag=0;
            }
        }

    }
    printf("end.\n");
    close(sockfd);
    return 0;
}

/*伺服器*/
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define BUFFER_SIZE 256
#define PORT 4568
char recv_buff[BUFFER_SIZE];
char send_buff[BUFFER_SIZE];
int main(void)
{
    char write_flag=0;
    char read_flag=1;
    int sockfd,newsockfd;// 套結字
    socklen_t addr_len;
    struct sockaddr_in ser_addr;//伺服器的IPv4的套結字結構
    addr_len=sizeof(struct sockaddr_in);
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)//建立套結字
    {
        perror("socket");
        exit(1);
    }
    else
    {
        printf("creat socket success id:%d\n",sockfd);
    }
    bzero(&ser_addr,sizeof(struct sockaddr_in));
    ser_addr.sin_family=AF_INET;
    ser_addr.sin_port=htons(PORT);
    ser_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    if(bind(sockfd,(struct sockaddr *)(&ser_addr),sizeof(struct sockaddr))<0)//繫結
    {
        perror("bind");
        exit(2);
    }
    else
    {
        printf("bind success.\n");
    }
    if(listen(sockfd,10)<0)//最多允許10個客戶端程序請求,監聽
    {
        perror("listen");
        exit(3);
    }
    else
    {
        printf("listening.....\n");
    }
    memset(send_buff,0x00,sizeof(send_buff));
    memset(recv_buff,0x00,sizeof(send_buff));
    if((newsockfd=accept(sockfd,(struct sockaddr*)(&ser_addr),&addr_len))<0)
    {
        //accept函式使用錯誤注意複習
        perror("accept");
        exit(4);
    }
    else
    {
        printf("connect success.\n");
    }
    write(newsockfd,"have connect!",strlen("have connect"));
    while(1)
    {
       if(strlen(send_buff)==0&&write_flag==1)//判斷髮送緩衝區是否為空
        {

            gets(send_buff);
            if(write(newsockfd,send_buff,strlen(send_buff))<0)
            {
                perror("write");
                exit(3);
            }
            else
            {
                printf("Client:\n");
                printf("       %s\n",send_buff);
            }
            read_flag=1;
            write_flag=0;
            memset(recv_buff,0x00,strlen(recv_buff));
        }
       else if(strlen(recv_buff)==0&&read_flag==1)
        {

            if(read(newsockfd,recv_buff,sizeof(recv_buff))<0)
            {
                perror("read");
                exit(4);
            }
            else if(strlen(recv_buff)>0)
            {
                printf("Server:\n");
                printf("      : %s\n",recv_buff);
                memset(send_buff,0x00,strlen(send_buff));//接受到資料後清空傳送緩衝區
                write_flag=1;
                read_flag=0;
            }
        }

    }
    close(sockfd);
    return 0;
}

效果圖: