聊天程序的简单实现
功能:
实现两个主机之间的局域网聊天
实现关键:
如何同时处理套接字的输入和标准输入 --- select函数
客户端的程序
#include "unp.h"void cli_echo(FILE *fp, int sockfd){int maxfdp1, stdineof;fd_set rset;char buf[1000];int n;stdineof=0;FD_ZERO(&rset);for(;;){if(stdineof==0)FD_SET(fileno(fp),&rset);FD_SET(sockfd,&rset);maxfdp1=max(fileno(fp), sockfd)+1;Select(maxfdp1, &rset, NULL, NULL, NULL);if(FD_ISSET(sockfd, &rset)) {//socket is readableif( (n=Read(sockfd, buf, 1000))==0){if(stdineof==1)return;//normal terminationelseerr_quit("cli_echo: server terminated prematurely");}Write(fileno(stdout),buf,n);}if(FD_ISSET(fileno(fp), &rset)){//input is readableif( (n=Read(fileno(fp),buf,1000))==0){stdineof=1;Shutdown(sockfd, SHUT_WR);FD_CLR(fileno(fp), &rset);continue;}Writen(sockfd, buf, n);}}}intmain(int argc, char **argv){int sockfd;struct sockaddr_in servaddr;if(argc!=2)err_quit("usage: tcpcli <IPaddress>");sockfd=Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_port=htons(1234);Inet_pton(AF_INET,argv[1], &servaddr.sin_addr);Connect(sockfd, (SA*) &servaddr, sizeof(servaddr));cli_echo(stdin,sockfd);exit(0);}
服务器端的程序
#include "unp.h"#include <time.h>void srv_echo(FILE *fp, int sockfd){int maxfdp1, stdineof;fd_set rset;char buf[1000];int n;stdineof=0;FD_ZERO(&rset);for(;;){if(stdineof==0)FD_SET(fileno(fp),&rset);FD_SET(sockfd,&rset);maxfdp1=max(fileno(fp), sockfd)+1;Select(maxfdp1, &rset, NULL, NULL, NULL);if(FD_ISSET(sockfd, &rset)) {//socket is readableif( (n=Read(sockfd, buf, 1000))==0){if(stdineof==1)return;//normal terminationelseerr_quit("srv_echo: client terminated prematurely");}Write(fileno(stdout),buf,n);}if(FD_ISSET(fileno(fp), &rset)){//input is readableif( (n=Read(fileno(fp),buf,1000))==0){stdineof=1;Shutdown(sockfd, SHUT_WR);FD_CLR(fileno(fp), &rset);continue;}Writen(sockfd, buf, n);}}}intmain(int argc, char **argv){int i, maxi, maxfd, listenfd, connfd, sockfd;socklen_t clilen;struct sockaddr_in cliaddr, servaddr;listenfd = Socket(AF_INET, SOCK_STREAM,0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_addr.s_addr=htonl(INADDR_ANY);servaddr.sin_port=htons(1234);Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));Listen(listenfd, LISTENQ);clilen=sizeof(cliaddr);connfd=Accept(listenfd, (SA*) &cliaddr, &clilen);srv_echo(stdin,connfd);Close(connfd);return 0;}
实现结果:
1. 先开启服务端 ./srv_echo
2. 再开启客户端 ./cli_echo 127.0.0.1
3. 任意在服务端或者客户端输入内容, 对端都将收到该内容

附件列表

浙公网安备 33010602011771号