首页 > 代码库 > 又延伸到socket去了。

又延伸到socket去了。

下面是我最近研究的用C写的Linux,socket聊天程序。要学Epoll,EPOLL中有很多socket的语句,所以又跳到C这边来了。

server.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/types.h>#include <unistd.h>#define BUFLEN 10#define SER_ADDR "127.0.0.1"#define PORT 8080#define MAX_CONN 200int main(int argc, char **argv){    int sockfd, newfd;    struct sockaddr_in s_addr, c_addr;    char buf[BUFLEN];    socklen_t len;    unsigned int port=8080, listnum=200;    /*简历socket*/    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)    {        perror("socket");        exit(errno);    }    else    {        printf("socket create success!\n");    }    /*设置侦听队列的长度*/    printf("listnum = %d", listnum);    /*设置服务器ip*/    bzero(&s_addr, sizeof(s_addr));    s_addr.sin_family = AF_INET;    s_addr.sin_port = htons(port);    printf("port= %d\n", port);    if(SER_ADDR)        s_addr.sin_addr.s_addr = inet_addr(SER_ADDR);    else        s_addr.sin_addr.s_addr = INADDR_ANY;    printf("socket_addr.addr = %d", s_addr.sin_addr.s_addr);    /*把地址和端口绑定到套接字上*/    if((bind(sockfd, (struct sockaddr*)&s_addr, sizeof(struct sockaddr))) == -1)    {        perror("bind");        exit(errno);    }    else    {        printf("bind success!\n");    }    /*侦听本地端口*/    if(listen(sockfd, listnum) == -1)    {        perror("listen");        exit(errno);    }    else        printf("the server is listening!\n");    while(1)    {        printf("**********聊天开始********\n");        len = sizeof(struct sockaddr);        if((newfd = accept(sockfd, (struct sockaddr*)&c_addr, &len)) == -1)        {            printf("a client connected\n");            perror("accept");            exit(errno);        }        else            printf("正在与您聊天的客户端是:%s:%d\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));        while(1)        {_retry:            /****发送消息****/            bzero(buf, BUFLEN);            printf("请输入发送对方的消息:");            /*fgets函数:从流中读取BUFLEN-1个字符*/            fgets(buf, BUFLEN, stdin);            /*打印发送的消息*/            //fputs(buf, stdout);            if(!strncasecmp(buf, "quit", 4))            {                printf("server请求终止聊天!\n");                break;            }            /*如果输入的字符串只有"\n", 即回车,那么轻重新输入*/            if(!strncmp(buf, "\n", 1))            {                printf("输入的字符只有回车, 这个是不正确的!!!\n");                goto _retry;            }            /*如果buf中含有‘\n‘, 那么要用strlen(buf)-1, 去掉‘\n‘*/            if(strchr(buf, ‘\n‘))                len = send(newfd, buf, strlen(buf)-1, 0);            /*如果buf中没有‘\n‘,则用buf的真正长度strlen(buf)*/            else                len = send(newfd, buf, strlen(buf), 0);            if(len > 0)                printf("消息发送成功,本次发送的字节数是:%d\n", len);            else            {                printf("消息发送失败!\n");                break;            }            /*****接受消息******/            bzero(buf, BUFLEN);            len = recv(newfd, buf, BUFLEN, 0);            if(len > 0)                printf("客户端发来的信息是:%s, 共有字节数是:%d\n", buf, len);            else            {                if(len<0)                    printf("接受消息失败!\n");                else                    printf("客户端退出了,聊天终止!\n");                break;            }        }        /*关闭聊天的套接字*/        close(newfd);        /*是否退出服务器*/        printf("服务器是否退出程序:y->是;n->否?");        bzero(buf, BUFLEN);        fgets(buf, BUFLEN, stdin);        if(!strncasecmp(buf, "y", 1))        {            printf("server退出!\n");            break;        }    }    /*关闭服务器的套接字*/    close(sockfd);    return 0;}

  client.c

#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <arpa/inet.h>#include <netinet/in.h>#include <unistd.h>#define BUFLEN 100int main(int argc, char **argv){    int sockfd;    struct sockaddr_in s_addr;    socklen_t len;    unsigned int port=8080;    char buf[BUFLEN];    /*简历socket*/    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)    {        perror("socket");        exit(errno);    }    else        printf("socket create success!\n");    /*设置服务器ip*/    bzero(&s_addr, sizeof(s_addr));    s_addr.sin_family=AF_INET;    s_addr.sin_port = htons(port);    char *server_addr = "127.0.0.1";    if(inet_aton(server_addr, (struct in_addr*)&s_addr.sin_addr.s_addr) == 0)    {        perror(server_addr);        exit(errno);    }    printf("s_addr.sin_addr.s_addr = %d", s_addr.sin_addr.s_addr);    /*开始连接服务器*/    if(connect(sockfd, (struct sockaddr*)&s_addr, sizeof(struct sockaddr)) != 0)    {        printf("connect failed");        perror("connect");        exit(errno);    }    else        printf("connect success! %d \n", errno);    printf("enter the while loop");    while(1)    {        printf("while");        /**接受消息**/        bzero(buf, BUFLEN);        len = recv(sockfd, buf, BUFLEN, 0);        if(len > 0)            printf("服务器发送来的消息是:%s,共有字节数是:%d\n", buf, len);        else        {            printf("else");            if(len < 0)                printf("接受消息失败!\n");            else                printf("服务器退出了,聊天终止!\n");            break;        }_retry:        /***发送消息***/        bzero(buf, BUFLEN);        printf("请输入发送给对方的消息:");        /*fgets函数:从流中读取BUFLEN-1个字符*/        fgets(buf, BUFLEN, stdin);        /*打印发送的消息*/        //fputs(buf, stdout);        if(!strncasecmp(buf, "quit", 4))        {            printf("client请求终止聊天!\n");            break;        }        /*如果输入的字符串只有‘\n‘,即回车, 那么请重新输入*/        if(!strncmp(buf, "\n", 1))        {            printf("输入的字符只有回车,这个是不正确的!!!\n");            goto _retry;        }        printf("%s", buf);        /*如果buf中含有‘\n‘, 那么要用strlen(buf)-1,去掉‘\n‘*/        if(strchr(buf, ‘\n‘))        {            printf("start to send");            len = send(sockfd, buf, strlen(buf)-1, 0);        }        /*如果buf中没有\n,则用buf的真正长度strlen(buf)*/        else            len = send(sockfd, buf, strlen(buf), 0);        printf("len = %d", len);        if(len > 0)            printf("消息发送成功,本次共发送的字节数是:%d\n", len);        else        {            printf("消息发送失败!\n");            break;        }    }    /*关闭连接*/    close(sockfd);    return 0;}

  

另外最近在看《C和指针》,断断续续看了点。今天记录一个比较有意思的

对于常量

int const a;

const int a;

这两种申明都是规范的。

int *pi;  pi是一个普通的指向整形的指针。

int const *cpi;    pci是一个指向整型常量的指针, 你可以修改指针的值,但是不能修改它所指向的值。

int * const cpi;    cpi是一个指向整形的常量指针。指针是常量,他的值无法修改,但是你可以修改它所指向的整型。

int const * const cpci;     无论是指针本身还是指针所指向的值都是常量,不能修改。