#2
月夜神宏2012-03-10 00:18
|
程序代码:
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<stdio.h>
#include<sys/select.h>
#include<iostream>
using namespace std;
#define MAXLEN 1000
int client[FD_SETSIZE]; //用来存放当前以链接的套接字
int maxi; //记录client数组以用的最大下标
int sendToAll(int sockfd, int maxi)
{
char buff[MAXLEN];
int n;
if( (n = read(sockfd, buff, MAXLEN)) == 0)
return 0;
for(int i=0; i<= maxi; ++i ) {
if( client[i] >=0 && client[i] != sockfd) {
write(client[i], buff, n);
}
}
return n;
}
int main() {
//创建监听套接字
int listenSockd;
if( (listenSockd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
fputs("socket error", stderr);
return -1;
}
//绑定地址和接口
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(listenSockd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) {
fputs("bind error", stderr);
return -1;
}
//开始接听
listen(listenSockd, 10);
//初始化client数组和maxi, client数组值为-1表示未用
maxi = -1;
for(int i=0; i< FD_SETSIZE; ++i)
client[i] = -1;
//设置select监听事件
int maxfd = listenSockd+1;
fd_set rset, allset; //allset为每次需要监听的事件,rset为监听到的事件
FD_ZERO(&allset);
FD_SET(listenSockd, &allset);
while(1) {
rset = allset;
int nready;
nready = select(maxfd, &rset, NULL, NULL, NULL);
//判断是否有新的连接
if(FD_ISSET(listenSockd, &rset)) {
int connfd,i;
connfd = accept(listenSockd, NULL, NULL);
//找到最前面没有被使用的,然后把新的套接字存入其中,
//同时更新allset和maxi
for(i = 0; i < FD_SETSIZE; ++i) {
if(client[i] < 0) {
client[i] = connfd;
FD_SET(connfd, &allset);
if( connfd >= maxfd )
maxfd = connfd + 1;
break;
}
}
if( i > FD_SETSIZE) {
fputs("too many clients", stderr);
return -1;
}
if(i > maxi)
maxi = i;
if(--nready <= 0) continue;
}
//判断是否有套接字已经准备好读
for(int i=0; i<= maxi; ++i) {
if(client[i] < 0 ) continue;
if(FD_ISSET(client[i], &rset)) {
if( sendToAll(client[i], maxi) == 0 ) {
client[i] = -1;
FD_CLR(client[i], &allset);
shutdown(client[i], SHUT_RDWR);
}
if(--nready <= 0 ) break;
}
}
}
return 0;
}
#include<netinet/in.h>
#include<string.h>
#include<stdio.h>
#include<sys/select.h>
#include<iostream>
using namespace std;
#define MAXLEN 1000
int client[FD_SETSIZE]; //用来存放当前以链接的套接字
int maxi; //记录client数组以用的最大下标
int sendToAll(int sockfd, int maxi)
{
char buff[MAXLEN];
int n;
if( (n = read(sockfd, buff, MAXLEN)) == 0)
return 0;
for(int i=0; i<= maxi; ++i ) {
if( client[i] >=0 && client[i] != sockfd) {
write(client[i], buff, n);
}
}
return n;
}
int main() {
//创建监听套接字
int listenSockd;
if( (listenSockd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
fputs("socket error", stderr);
return -1;
}
//绑定地址和接口
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(listenSockd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) {
fputs("bind error", stderr);
return -1;
}
//开始接听
listen(listenSockd, 10);
//初始化client数组和maxi, client数组值为-1表示未用
maxi = -1;
for(int i=0; i< FD_SETSIZE; ++i)
client[i] = -1;
//设置select监听事件
int maxfd = listenSockd+1;
fd_set rset, allset; //allset为每次需要监听的事件,rset为监听到的事件
FD_ZERO(&allset);
FD_SET(listenSockd, &allset);
while(1) {
rset = allset;
int nready;
nready = select(maxfd, &rset, NULL, NULL, NULL);
//判断是否有新的连接
if(FD_ISSET(listenSockd, &rset)) {
int connfd,i;
connfd = accept(listenSockd, NULL, NULL);
//找到最前面没有被使用的,然后把新的套接字存入其中,
//同时更新allset和maxi
for(i = 0; i < FD_SETSIZE; ++i) {
if(client[i] < 0) {
client[i] = connfd;
FD_SET(connfd, &allset);
if( connfd >= maxfd )
maxfd = connfd + 1;
break;
}
}
if( i > FD_SETSIZE) {
fputs("too many clients", stderr);
return -1;
}
if(i > maxi)
maxi = i;
if(--nready <= 0) continue;
}
//判断是否有套接字已经准备好读
for(int i=0; i<= maxi; ++i) {
if(client[i] < 0 ) continue;
if(FD_ISSET(client[i], &rset)) {
if( sendToAll(client[i], maxi) == 0 ) {
client[i] = -1;
FD_CLR(client[i], &allset);
shutdown(client[i], SHUT_RDWR);
}
if(--nready <= 0 ) break;
}
}
}
return 0;
}
客户端程序:
程序代码:
#include<sys/socket.h>
#include<stdio.h>
#include<sys/select.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<assert.h>
#define MAXLEN 1000
int main(int argc, char *argv[])
{
assert( argc >= 2 );
int sockfd;
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fputs("socket error", stderr);
return -1;
}
struct sockaddr_in clientaddr;
bzero(&clientaddr, sizeof(clientaddr));
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(8888);
inet_pton(AF_INET, argv[1], &clientaddr.sin_addr);
if( connect(sockfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr)) < 0){
fputs("connect error", stderr);
return -1;
}
int flag = 0;
char recvBuff[MAXLEN], sendBuff[MAXLEN];
fd_set rset;
FD_ZERO(&rset);
while( 1 ) {
FD_SET(sockfd, &rset);
if( !flag)
FD_SET(fileno(stdin), &rset);
select(sockfd+1, &rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd, &rset)) {
int n;
if((n = read(sockfd, recvBuff, MAXLEN)) == 0){
if(flag) return 0;
else {
fputs("read error", stderr);
return -1;
}
}
recvBuff[n] = '\0';
fputs(recvBuff, stdout);
}
if(FD_ISSET(fileno(stdin), &rset)){
int n;
if((n = read(fileno(stdin), sendBuff, MAXLEN)) == 0) {
flag = 1;
FD_CLR(fileno(stdin), &rset);
shutdown(sockfd, SHUT_WR);
continue;
}
write(sockfd, sendBuff, n);
}
}
return 0;
}
#include<stdio.h>
#include<sys/select.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<assert.h>
#define MAXLEN 1000
int main(int argc, char *argv[])
{
assert( argc >= 2 );
int sockfd;
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fputs("socket error", stderr);
return -1;
}
struct sockaddr_in clientaddr;
bzero(&clientaddr, sizeof(clientaddr));
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(8888);
inet_pton(AF_INET, argv[1], &clientaddr.sin_addr);
if( connect(sockfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr)) < 0){
fputs("connect error", stderr);
return -1;
}
int flag = 0;
char recvBuff[MAXLEN], sendBuff[MAXLEN];
fd_set rset;
FD_ZERO(&rset);
while( 1 ) {
FD_SET(sockfd, &rset);
if( !flag)
FD_SET(fileno(stdin), &rset);
select(sockfd+1, &rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd, &rset)) {
int n;
if((n = read(sockfd, recvBuff, MAXLEN)) == 0){
if(flag) return 0;
else {
fputs("read error", stderr);
return -1;
}
}
recvBuff[n] = '\0';
fputs(recvBuff, stdout);
}
if(FD_ISSET(fileno(stdin), &rset)){
int n;
if((n = read(fileno(stdin), sendBuff, MAXLEN)) == 0) {
flag = 1;
FD_CLR(fileno(stdin), &rset);
shutdown(sockfd, SHUT_WR);
continue;
}
write(sockfd, sendBuff, n);
}
}
return 0;
}