为了更深刻的锻炼认识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;
}

效果图:








GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐