• 聊天程序的简单实现


    功能:

    实现两个主机之间的局域网聊天


    实现关键:

    如何同时处理套接字的输入和标准输入 --- select函数


    客户端的程序

    1. #include "unp.h"
    2. void cli_echo(FILE *fp, int sockfd)
    3. {
    4. int maxfdp1, stdineof;
    5. fd_set rset;
    6. char buf[1000];
    7. int n;
    8. stdineof=0;
    9. FD_ZERO(&rset);
    10. for(;;){
    11. if(stdineof==0)
    12. FD_SET(fileno(fp),&rset);
    13. FD_SET(sockfd,&rset);
    14. maxfdp1=max(fileno(fp), sockfd)+1;
    15. Select(maxfdp1, &rset, NULL, NULL, NULL);
    16. if(FD_ISSET(sockfd, &rset)) {//socket is readable
    17. if( (n=Read(sockfd, buf, 1000))==0){
    18. if(stdineof==1)
    19. return;//normal termination
    20. else
    21. err_quit("cli_echo: server terminated prematurely");
    22. }
    23. Write(fileno(stdout),buf,n);
    24. }
    25. if(FD_ISSET(fileno(fp), &rset)){//input is readable
    26. if( (n=Read(fileno(fp),buf,1000))==0){
    27. stdineof=1;
    28. Shutdown(sockfd, SHUT_WR);
    29. FD_CLR(fileno(fp), &rset);
    30. continue;
    31. }
    32. Writen(sockfd, buf, n);
    33. }
    34. }
    35. }
    36. int
    37. main(int argc, char **argv)
    38. {
    39. int sockfd;
    40. struct sockaddr_in servaddr;
    41. if(argc!=2)
    42. err_quit("usage: tcpcli <IPaddress>");
    43. sockfd=Socket(AF_INET, SOCK_STREAM, 0);
    44. bzero(&servaddr, sizeof(servaddr));
    45. servaddr.sin_family=AF_INET;
    46. servaddr.sin_port=htons(1234);
    47. Inet_pton(AF_INET,argv[1], &servaddr.sin_addr);
    48. Connect(sockfd, (SA*) &servaddr, sizeof(servaddr));
    49. cli_echo(stdin,sockfd);
    50. exit(0);
    51. }

    服务器端的程序

    1. #include "unp.h"
    2. #include <time.h>
    3. void srv_echo(FILE *fp, int sockfd)
    4. {
    5. int maxfdp1, stdineof;
    6. fd_set rset;
    7. char buf[1000];
    8. int n;
    9. stdineof=0;
    10. FD_ZERO(&rset);
    11. for(;;){
    12. if(stdineof==0)
    13. FD_SET(fileno(fp),&rset);
    14. FD_SET(sockfd,&rset);
    15. maxfdp1=max(fileno(fp), sockfd)+1;
    16. Select(maxfdp1, &rset, NULL, NULL, NULL);
    17. if(FD_ISSET(sockfd, &rset)) {//socket is readable
    18. if( (n=Read(sockfd, buf, 1000))==0){
    19. if(stdineof==1)
    20. return;//normal termination
    21. else
    22. err_quit("srv_echo: client terminated prematurely");
    23. }
    24. Write(fileno(stdout),buf,n);
    25. }
    26. if(FD_ISSET(fileno(fp), &rset)){//input is readable
    27. if( (n=Read(fileno(fp),buf,1000))==0){
    28. stdineof=1;
    29. Shutdown(sockfd, SHUT_WR);
    30. FD_CLR(fileno(fp), &rset);
    31. continue;
    32. }
    33. Writen(sockfd, buf, n);
    34. }
    35. }
    36. }
    37. int
    38. main(int argc, char **argv)
    39. {
    40. int i, maxi, maxfd, listenfd, connfd, sockfd;
    41. socklen_t clilen;
    42. struct sockaddr_in cliaddr, servaddr;
    43. listenfd = Socket(AF_INET, SOCK_STREAM,0);
    44. bzero(&servaddr, sizeof(servaddr));
    45. servaddr.sin_family=AF_INET;
    46. servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    47. servaddr.sin_port=htons(1234);
    48. Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
    49. Listen(listenfd, LISTENQ);
    50. clilen=sizeof(cliaddr);
    51. connfd=Accept(listenfd, (SA*) &cliaddr, &clilen);
    52. srv_echo(stdin,connfd);
    53. Close(connfd);
    54. return 0;
    55. }


    实现结果:

    1. 先开启服务端 ./srv_echo

    2. 再开启客户端 ./cli_echo 127.0.0.1

    3. 任意在服务端或者客户端输入内容, 对端都将收到该内容







    附件列表

    • 相关阅读:
      leetcode 189. Rotate Array 数组旋转 ---------- java
      Google test Problem A. Country Leader
      leetcode 187. Repeated DNA Sequences 求重复的DNA串 ---------- java
      mysql忘记密码(未初始化)
      leetcode 186. Reverse Words in a String II 旋转字符数组 ---------- java
      CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate)(转载)
      bootstrap
      bootstrap使用中遇到的问题(二)
      兼容ie8 rgba()用法
      浏览器前缀
    • 原文地址:https://www.cnblogs.com/gremount/p/5803107.html
    Copyright © 2020-2023  润新知