select实现的点对点聊天室(linux应用层编程期末作业)
server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <string.h>
#define BUFSIZE 100
int main()
{
int sock_fd, client_fd;
int max_fd;
fd_set readfdset;
struct sockaddr_in server_addr;
struct timeval timeout;
char buf[BUFSIZE];
int ret;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if((sock_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket creating error");
exit(-1);
}
if(bind(sock_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
{
perror("bind error");
exit(-1);
}
if(listen(sock_fd, 5) < 0)
{
perror("listen error");
exit(-1);
}
if((client_fd = accept(sock_fd, NULL, NULL)) < 0)
{
perror("accept error");
exit(-1);
}
while(1)
{
bzero(buf, sizeof(buf));
FD_ZERO(&readfdset);
FD_SET(0, &readfdset);
FD_SET(client_fd, &readfdset);
if(select(client_fd+ 1, &readfdset, NULL, NULL, &timeout) < 0)
{
perror("select error");
exit(-1);
}
if(FD_ISSET(client_fd, &readfdset))
{
if((ret = recv(client_fd, buf, sizeof(buf), 0)) <= 0)
{
close(sock_fd);
close(client_fd);
if(ret < 0)
perror("recv error");
else
printf("exceptional client close\n");
exit(-1);
}
if(strncmp(buf, "quit", 4) == 0)
{
printf("client quit\n");
close(sock_fd);
close(client_fd);
return 0;
}
printf("client: %s\n", buf);
}
if(FD_ISSET(0, &readfdset))
{
if(read(0, buf, sizeof(buf)) < 0)
{
perror("read error");
exit(-1);
}
if(send(client_fd, buf, sizeof(buf), 0) < 0)
{
perror("send error");
exit(-1);
}
if(strncmp(buf, "quit", 4) == 0)
{
printf("server quit\n");
close(sock_fd);
close(client_fd);
return 0;
}
printf("server: %s\n", buf);
}
}
return 0;
}
client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/select.h>
#define BUFSIZE 100
int main()
{
int sock_fd;
int max_fd;
fd_set readfdset;
struct sockaddr_in bind_addr, server_addr;
struct timeval timeout;
char buf[BUFSIZE];
int ret;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons(6666);
bind_addr.sin_addr.s_addr = inet_addr("127.0.0.2");
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket creating error");
exit(-1);
}
if(bind(sock_fd, (struct sockaddr *) &bind_addr, sizeof(bind_addr)) < 0)
{
perror("bind error");
exit(-1);
}
if(connect(sock_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
{
perror("connect error:please check the server_addr struct or make sure that server has already opened");
exit(-1);
}
while(1)
{
bzero(buf, sizeof(buf));
FD_ZERO(&readfdset);
FD_SET(0, &readfdset);
FD_SET(sock_fd, &readfdset);
if(select(sock_fd + 1, &readfdset, NULL, NULL, &timeout) < 0)
{
perror("select error");
exit(-1);
}
if(FD_ISSET(sock_fd, &readfdset))
{
if((ret = recv(sock_fd, buf, sizeof(buf), 0)) <= 0)
{
close(sock_fd);
if(ret < 0)
perror("recv error");
else
printf("exceptional server close\n");
exit(-1);
}
if(strncmp(buf, "quit", 4) == 0)
{
printf("server quit\n");
close(sock_fd);
return 0;
}
printf("server: %s\n", buf);
}
if(FD_ISSET(0, &readfdset))
{
if(read(0, buf, sizeof(buf)) < 0)
{
perror("read error");
exit(-1);
}
if(send(sock_fd, buf, sizeof(buf), 0) < 0)
{
perror("send error");
exit(-1);
}
if(strncmp(buf, "quit", 4) == 0)
{
close(sock_fd);
printf("client quit\n");
return 0;
}
printf("client: %s\n", buf);
}
}
return 0;
}
编译语句
gcc -g server.c -o server
gcc -g client.c -o client