/*客户:从命令行接收服务器地址,并向服务器发起连接请求,连接成功后, 从标准输入接收字符串并发送给服务器,等待服务器响应并打印接收的信息。*/ #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define PORT 2088 #define MAXLINE 100 int main(int argc, char *argv[]) { int fd,n; char sendline[MAXLINE],recvline[MAXLINE]; struct hostent * he; struct sockaddr_in server; if (argc != 2) { printf("Usage: %s <IP address>\n", argv[0]); exit(1); } //获取主机名 if ((he = gethostbyname(argv[1])) == NULL) { perror("gethostbyname error."); exit(1); } if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Create socket failed."); exit(1); } //初始化地址结构 bzero(&server, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr = *((struct in_addr *) he->h_addr);//inet_pton(AF_INET,argv[1],&server.sin_addr);也行 //连接到服务器 if (connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) { perror("connect failed!"); exit(1); } else printf("Connect Success!\n"); //输入客户name,服务器显示 printf("Input your name:"); if(fgets(sendline,MAXLINE,stdin)!=NULL) write(fd,sendline,strlen(sendline)); //循环从命令行读入一行字符串,并发送到服务器 printf("Input a string:"); while((fgets(sendline,MAXLINE,stdin))!=NULL) { //发送数据到服务器 write(fd,sendline,strlen(sendline)); //接收从服务器发来的数据 if((n=recv(fd,recvline,MAXLINE,0))==0) { perror("server terminated prematurely!"); return; } recvline[n]='\0'; printf("recieve data from server:%s\n",recvline); printf("Input a string:"); //fputs(recvline,stdout); } //关闭fd close(fd); exit(0); } /*服务器利用I/O复用技术,实现同时向多个客户提供服务。要求: 服务器:接收客户连接请求,并打印客户IP地址及端口号,然后接收客户发来的字符串,并打印该字符串和其来自与哪个客户。 同时向客户返回该字符串。当某一客户断开连接时,要求服务器打印该客户输入的所有字符。*/ #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <string.h> #include <malloc.h> #include <sys/select.h> #include<fcntl.h> #define MAXSIZE 100 #define PORT 2088 #define BACKLOG 10 typedef struct CLIENT{ int fd; char *name; struct sockaddr_in client_addr; char *data; }CLIENT; void process_cli(CLIENT *client, char *recvbuf, int len); //void savedata(char *recvbuf ,int len,char *savebuf); int main(void) { int i, maxi, maxfd, sockfd; int nready; ssize_t n; fd_set rset, allset; int listenfd,connectfd; struct sockaddr_in server,addr; CLIENT client[FD_SETSIZE]; char recvbuf[MAXSIZE],buff[MAXSIZE]; int sin_size; //创建监听套接字 if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1) { perror("Create socket failed\n"); exit(0); } //int flag=fcntl(sockfd,F_GETFL,0); //fcntl(sockfd,F_SETFL,flag|O_NONBLOCK); int opt=SO_REUSEADDR; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));//socket重用,不再等待close_wait //初始化地址结构 bzero(&server,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(PORT); server.sin_addr.s_addr=htonl(INADDR_ANY); //绑定地址 if(bind(listenfd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1) { perror("Bind error\n"); exit(0); } //监听 if(listen(listenfd,BACKLOG)==-1) { perror("listen error\n"); exit(0); } maxfd = listenfd; maxi = -1; for (i =0; i< FD_SETSIZE; i++) client[i].fd = -1; FD_ZERO(&allset);//清零 FD_SET(listenfd, &allset);//打开 while (1) { rset = allset; nready = select (maxfd+1, &rset, NULL, NULL, NULL); if (FD_ISSET(listenfd, &rset)) { sin_size = sizeof(addr); if ((connectfd = accept(listenfd, (struct sockaddr *)&addr, &sin_size)) == -1) { perror("accept error\n"); continue; } for (i = 0; i < FD_SETSIZE; i++) if (client[i].fd < 0) { client[i].fd = connectfd; client[i].name =(char*)malloc(MAXSIZE); client[i].client_addr = addr; client[i].data =(char*)malloc(MAXSIZE); client[i].name[0] = '\0'; client[i].data[0] = '\0'; printf("You got a connect from :%s port:%d\n",inet_ntoa(client[i].client_addr.sin_addr),ntohs(client[i].client_addr.sin_port)); //printf("Connect from %s, port is %d \n",inet_ntop(AF_INET,&client[i].client_addr .sin_addr,buff,sizeof(buff)),ntohs(client[i].client_addr .sin_port)); break; } if (i == FD_SETSIZE) printf("too many cllients.\n"); FD_SET(connectfd, &allset); if (connectfd > maxfd) maxfd = connectfd; if (i > maxi) maxi =i; if ( -- nready <=0) continue; } for (i=0; i<=maxi;i++) { if ((sockfd = client[i].fd) < 0) continue; if (FD_ISSET(sockfd, &rset)) { if (( n = recv(sockfd, recvbuf, MAXSIZE, 0))==0) { close(sockfd); printf("Client (%s) closed connection. User’s data: %s\n", client[i].name, client[i].data); FD_CLR(sockfd, &allset); client[i].fd = -1; free(client[i].name); free(client[i].data); } else process_cli(&client[i], recvbuf, n); if ( --nready <=0 ) break; } } } close(listenfd); } void process_cli(CLIENT *client, char *recvbuf, int len) { char sendbuf[MAXSIZE]; recvbuf[len-1]=0; if(strlen(client->name)==0) { memcpy(client->name,recvbuf,len); printf("client's name is %s\n",client->name); return; } printf("received client (%s) message :%s \n",client->name,recvbuf); strcat(client->data,recvbuf); send(client->fd,recvbuf,strlen(recvbuf),0); }