冯伟浩 2012.6.5 C/S-单播
来源:互联网 发布:winhex数据恢复收费吗 编辑:程序博客网 时间:2024/05/13 15:36
作者:2010级嵌入式 冯伟浩
问题由来: http://blog.chinaunix.net/uid-14735472-id-3216962.html
++++++++++++++++++++++++++++++++++
[root@bogon ~]# gedit server.c/* server.c */
#include
#include
#include
#include
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
char buf[MAXLINE];
int client[FD_SETSIZE];
int i;
int maxi;
int doit(char *var, char *vbr);
int main(int argc, char **argv)
{
int i, maxi, maxfd, listenfd, connfd, sockfd; int p=0,l=0,k=0,j;
int nready, client[FD_SETSIZE];
ssize_t n;
pthread_t tidA;
fd_set rset, allset;
char buf[MAXLINE];
memset(buf,0,MAXLINE);
char str[INET_ADDRSTRLEN];
socklen_t cliaddr_len;
struct sockaddr_in cliaddr, servaddr;
char dbuf[]="--";
char cbuf[]="已登录!";
char fbuf[]="收到的信息";
char ebuf[]="用户已登录!请重新打开窗口输入!";
char sookset1[MAXLINE][MAXLINE];
memset(sookset1,0,MAXLINE*MAXLINE*sizeof(char));
char buf2[MAXLINE][MAXLINE];
char buf3[MAXLINE][MAXLINE];
memset(buf3,0,MAXLINE*MAXLINE*sizeof(char));
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(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
Listen(listenfd, 20);
maxfd = listenfd;
maxi = -1;
for (i = 0; i client[i] = -1;
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
for (;;) {
rset = allset;
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);//剔除
if (nready < 0)
perr_exit("select error");
if (FD_ISSET(listenfd, &rset)) {
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
printf("received from %s at PORT %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] < 0) {
printf("i=%d\n",i);
//打印I的值,i从0开始加
client[i] = connfd; /* save descriptor */
sookset1[i][0]=connfd;
//定义二维数组只用下标为[i][0]的位置来存放文件描述符!每打开一个客户端链接i的值自动的加加。。i从0开始加..存放客户端文件描述符的分别是[0][0],[1][0],[2][0]
printf("sookset1[p][0]=%s\n",sookset1[p]);
//控制流程将sookset1[p]的值打印出来。
break;
}
if (i == FD_SETSIZE) {
fputs("too many clients\n", stderr);
exit(1);
}
FD_SET(connfd, &allset);
if (connfd > maxfd)
maxfd = connfd;
if (i > maxi)
maxi = i;
if (--nready == 0)
continue;
}
for (i = 0; i <= maxi; i++) {
if ( client[i] < 0)
{continue;}else
{
sockfd = client[i];
}
lable1: if (FD_ISSET(sockfd, &rset)) {
memset(buf,0,MAXLINE);
if ((n = Read(sockfd, buf, MAXLINE)) == 0) {
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
} else {
printf("maxi=%d\n",maxi);
for(j = 0; j <= maxi; j++)
{
printf("buf3[1]=%s\n",buf3[j]);
printf("buf=%s\n",buf);
if(strcmp(buf3[j],buf)==0)
{
for (i = 0; i <= maxi; i++)
{
Write(client[i], ebuf, n);
} goto lable1;
}
}
if(strstr(buf,dbuf)==NULL)
//用来判断客户端输入的是用户名还是信息!查找buf中是否含有dbuf,我觉的这个用的不好,但是一时也没想开咋该。
{
printf("执行了一次!\n"); //成功执行这下面的代码,控制流程
printf("i=%d\n",i); //打印活动的文件描述符的下标!从0开始
strcat(sookset1[i],buf);//将文件描述符和用户输入的用户名进行链接,分别放入sookset1中
printf("sookset1[i]=%s\n",sookset1[i]); //打印链接后的sookset1[i]
strcat(buf2[i],buf);
strcat(buf3[i],buf);
printf("buf2[i]=%s\n",buf2[i]);
strcat(buf2[i],dbuf);//必须是英文情况下的--
strcat(buf2[i],cbuf);//执行后即为谁--已登录
//strcat(buf2[i],buf);
for (i = 0; i <= maxi; i++)
for (j = 0; j<= maxi; j++)
{
Write(client[i], buf2[j], n);//每次客户运行将已登录的信息循环发给每个用户
}//将客户端输入的信息循环写入
}else{ //如果输入的是信息执行下列代码
for(j=0;j<=maxi;j++)
{
printf("打印@\n");
printf("buf=%s\n",buf);//将读入的客户端信息放入buf中并打印
printf("sookset1[j]=%s\n",sookset1[j]); //将此时sookset1[j]的信息打印出来
if(doit(sookset1[j],buf)==1)//判断sookset1[j]的信息何buf的信息是否相等
{
printf("sookset1[j][0]=%c\n",sookset1[j][0]); //打印此时的文件描述符
j=(int)sookset1[j][0];//将sookset1[j][0]中的文件描述符转化为整形
printf("%d\n",j);
Write(j, buf, n);//将信息写入客户端
}
}
}
}
if (--nready == 0)
break;
}
}
}
}
int doit(char *var, char *vbr) //函数用来比较sookset1[j]和buf是否相等,此时sookset1[j]相当于一维字符串数组
{
int k;
for(k=0;k<10;k++)
{
if(var[k+1]=='-' || vbr[k]=='-')
//for循环下标从头开始比较,因为sookset1[j]中sookset1[j][0]为文件描述符所以从k+1处开始比较
{
break;
}else{
if(var[k+1]==vbr[k])
{
continue;
}else{
if(var[k+1]!=vbr[k])
{
return 0;
}
}
}
}
return 1;
}
++++++++++++++++++++++++++++++++++++
[root@bogon ~]# gedit client.c
/* client.c */
#include
#include
#include
#include
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
void *doit(void *arg);
char buf[MAXLINE];
int main(int argc, char *argv[])
{
struct sockaddr_in servaddr;
char buf[MAXLINE];
memset(buf,0,MAXLINE);
int sockfd, n;
pthread_t tidA;
if (argc != 2) {
fprintf(stderr,"请输入要发送的信息\n");
exit(1);
}
strcpy(buf,argv[1]);
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
printf("请输入用户名形如xxx--xxx\n");
printf("请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!\n");
printf("如果输入重复的用户名!请重新打开窗口!\n");
printf("请输入esc退出程序!\n");
Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
write(sockfd,buf,MAXLINE);
while (1) {
pid_t pid;
char *message;
int n;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
}
if (pid == 0) {
memset(buf,0,MAXLINE);
n = Read(sockfd, buf, MAXLINE);
if (n == 0)
{ printf("the servre has closed.\n");break; }
else
//Write(STDOUT_FILENO, buf, n);
printf("%s\n",buf);
printf("------------------------\n");
} else {
fgets(buf, MAXLINE, stdin);
if(memcmp(buf,"esc",3)==0)
{
exit(1);
}
Write(sockfd, buf, strlen(buf));
}
}
Close(sockfd);
return 0;
}
++++++++++++++++++++++++++++++++++++++++
[root@bogon ~]# gedit wrap.h
#include
#include
#include
void perr_exit(const char *s)
{
perror(s);
exit(1);
}
int Accept(int fd, struct sockaddr *sa, socklen_t * salenptr)
{
int n;
again:
if ((n = accept(fd, sa, salenptr)) < 0) {
if ((errno == ECONNABORTED) || (errno == EINTR))
goto again;
else
perr_exit("accept error");
}
return n;
}
void Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
if (bind(fd, sa, salen) < 0)
perr_exit("bind error");
}
void Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
if (connect(fd, sa, salen) < 0)
perr_exit("connect error");
}
void Listen(int fd, int backlog)
{
if (listen(fd, backlog) < 0)
perr_exit("listen error");
}
int Socket(int family, int type, int protocol)
{
int n;
if ((n = socket(family, type, protocol)) < 0)
perr_exit("socket error");
return n;
}
ssize_t Read(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
again:
if ((n = read(fd, ptr, nbytes)) == -1) {
if (errno == EINTR)
goto again;
else
return -1;
}
return n;
}
ssize_t Write(int fd, const void *ptr, size_t nbytes)
{
ssize_t n;
again:
if ((n = write(fd, ptr, nbytes)) == -1) {
if (errno == EINTR)
goto again;
else
return -1;
}
return n;
}
void Close(int fd)
{
if (close(fd) == -1)
perr_exit("close error");
}
ssize_t Readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0;
else
return -1;
} else if (nread == 0)
break;
nleft -= nread;
ptr += nread;
}
return n - nleft;
}
ssize_t Writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) <= 0) {
if (nwritten < 0 && errno == EINTR)
nwritten = 0;
else
return -1;
}
nleft -= nwritten;
ptr += nwritten;
}
return n;
}
static ssize_t my_read(int fd, char *ptr)
{
static int read_cnt;
static char *read_ptr;
static char read_buf[100];
if (read_cnt <= 0) {
again:
if ((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return -1;
} else if (read_cnt == 0)
return 0;
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return 1;
}
ssize_t Readline(int fd, void *vptr, size_t maxlen)
{
ssize_t n, rc;
char c, *ptr;
ptr = vptr;
for (n = 1; n < maxlen; n++) {
if ((rc = my_read(fd, &c)) == 1) {
*ptr++ = c;
if (c == '\n')
break;
} else if (rc == 0) {
*ptr = 0;
return n - 1;
} else
return -1;
}
*ptr = 0;
return n;
}
+++++++++++++++++++++++++++++
执行过程:
客户端一:[root@bogon select]# ./clie3 asd
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
asd--已登录!
------------------------
asd--已登录!
------------------------
qwe--已登录!
------------------------
asd--asdfsdfsdf //qwe给asd的信息
------------------------
qwe--asdfsdfdsf //发给qwe的信息
asd--已登录!
------------------------
qwe--已登录!
------------------------
zxc--已登录!
------------------------
asd--sadfdsf //zxc给asd的信息
------------------------
zxc--asdfdsf //回给zxc的信息
用户已登录!请重新打开窗口输入! // //将第四个重复的用户也广播出去!
客户端二:
[root@bogon select]# ./clie3 qwe
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
asd--已登录!
------------------------
qwe--已登录!
------------------------
asd--asdfsdfsdf 发给asd的信息
qwe--asdfsdfdsf asd 发给qwe的信息
------------------------
asd--已登录!
------------------------
qwe--已登录!
------------------------
zxc--已登录!
------------------------
用户已登录!请重新打开窗口输入! //将第四个重复的用户也广播出去!
------------------------
客户端三:
[root@bogon select]# ./clie3 zxc
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
asd--已登录!
------------------------
qwe--已登录!
------------------------
zxc--已登录!
------------------------
asd--sadfdsf
zxc--asdfdsf
------------------------
用户已登录!请重新打开窗口输入! // //将第四个重复的用户也广播出去!
------------------------
[root@bogon select]# ./clie3 asd //登录用户名重复!
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
用户已登录!请重新打开窗口输入!
------------------------
问题由来: http://blog.chinaunix.net/uid-14735472-id-3216962.html
++++++++++++++++++++++++++++++++++
[root@bogon ~]# gedit server.c/* server.c */
#include
#include
#include
#include
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
char buf[MAXLINE];
int client[FD_SETSIZE];
int i;
int maxi;
int doit(char *var, char *vbr);
int main(int argc, char **argv)
{
int i, maxi, maxfd, listenfd, connfd, sockfd; int p=0,l=0,k=0,j;
int nready, client[FD_SETSIZE];
ssize_t n;
pthread_t tidA;
fd_set rset, allset;
char buf[MAXLINE];
memset(buf,0,MAXLINE);
char str[INET_ADDRSTRLEN];
socklen_t cliaddr_len;
struct sockaddr_in cliaddr, servaddr;
char dbuf[]="--";
char cbuf[]="已登录!";
char fbuf[]="收到的信息";
char ebuf[]="用户已登录!请重新打开窗口输入!";
char sookset1[MAXLINE][MAXLINE];
memset(sookset1,0,MAXLINE*MAXLINE*sizeof(char));
char buf2[MAXLINE][MAXLINE];
char buf3[MAXLINE][MAXLINE];
memset(buf3,0,MAXLINE*MAXLINE*sizeof(char));
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(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
Listen(listenfd, 20);
maxfd = listenfd;
maxi = -1;
for (i = 0; i
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
for (;;) {
rset = allset;
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);//剔除
if (nready < 0)
perr_exit("select error");
if (FD_ISSET(listenfd, &rset)) {
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
printf("received from %s at PORT %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] < 0) {
printf("i=%d\n",i);
//打印I的值,i从0开始加
client[i] = connfd; /* save descriptor */
sookset1[i][0]=connfd;
//定义二维数组只用下标为[i][0]的位置来存放文件描述符!每打开一个客户端链接i的值自动的加加。。i从0开始加..存放客户端文件描述符的分别是[0][0],[1][0],[2][0]
printf("sookset1[p][0]=%s\n",sookset1[p]);
//控制流程将sookset1[p]的值打印出来。
break;
}
if (i == FD_SETSIZE) {
fputs("too many clients\n", stderr);
exit(1);
}
FD_SET(connfd, &allset);
if (connfd > maxfd)
maxfd = connfd;
if (i > maxi)
maxi = i;
if (--nready == 0)
continue;
}
for (i = 0; i <= maxi; i++) {
if ( client[i] < 0)
{continue;}else
{
sockfd = client[i];
}
lable1: if (FD_ISSET(sockfd, &rset)) {
memset(buf,0,MAXLINE);
if ((n = Read(sockfd, buf, MAXLINE)) == 0) {
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
} else {
printf("maxi=%d\n",maxi);
for(j = 0; j <= maxi; j++)
{
printf("buf3[1]=%s\n",buf3[j]);
printf("buf=%s\n",buf);
if(strcmp(buf3[j],buf)==0)
{
for (i = 0; i <= maxi; i++)
{
Write(client[i], ebuf, n);
} goto lable1;
}
}
if(strstr(buf,dbuf)==NULL)
//用来判断客户端输入的是用户名还是信息!查找buf中是否含有dbuf,我觉的这个用的不好,但是一时也没想开咋该。
{
printf("执行了一次!\n"); //成功执行这下面的代码,控制流程
printf("i=%d\n",i); //打印活动的文件描述符的下标!从0开始
strcat(sookset1[i],buf);//将文件描述符和用户输入的用户名进行链接,分别放入sookset1中
printf("sookset1[i]=%s\n",sookset1[i]); //打印链接后的sookset1[i]
strcat(buf2[i],buf);
strcat(buf3[i],buf);
printf("buf2[i]=%s\n",buf2[i]);
strcat(buf2[i],dbuf);//必须是英文情况下的--
strcat(buf2[i],cbuf);//执行后即为谁--已登录
//strcat(buf2[i],buf);
for (i = 0; i <= maxi; i++)
for (j = 0; j<= maxi; j++)
{
Write(client[i], buf2[j], n);//每次客户运行将已登录的信息循环发给每个用户
}//将客户端输入的信息循环写入
}else{ //如果输入的是信息执行下列代码
for(j=0;j<=maxi;j++)
{
printf("打印@\n");
printf("buf=%s\n",buf);//将读入的客户端信息放入buf中并打印
printf("sookset1[j]=%s\n",sookset1[j]); //将此时sookset1[j]的信息打印出来
if(doit(sookset1[j],buf)==1)//判断sookset1[j]的信息何buf的信息是否相等
{
printf("sookset1[j][0]=%c\n",sookset1[j][0]); //打印此时的文件描述符
j=(int)sookset1[j][0];//将sookset1[j][0]中的文件描述符转化为整形
printf("%d\n",j);
Write(j, buf, n);//将信息写入客户端
}
}
}
}
if (--nready == 0)
break;
}
}
}
}
int doit(char *var, char *vbr) //函数用来比较sookset1[j]和buf是否相等,此时sookset1[j]相当于一维字符串数组
{
int k;
for(k=0;k<10;k++)
{
if(var[k+1]=='-' || vbr[k]=='-')
//for循环下标从头开始比较,因为sookset1[j]中sookset1[j][0]为文件描述符所以从k+1处开始比较
{
break;
}else{
if(var[k+1]==vbr[k])
{
continue;
}else{
if(var[k+1]!=vbr[k])
{
return 0;
}
}
}
}
return 1;
}
++++++++++++++++++++++++++++++++++++
[root@bogon ~]# gedit client.c
/* client.c */
#include
#include
#include
#include
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
void *doit(void *arg);
char buf[MAXLINE];
int main(int argc, char *argv[])
{
struct sockaddr_in servaddr;
char buf[MAXLINE];
memset(buf,0,MAXLINE);
int sockfd, n;
pthread_t tidA;
if (argc != 2) {
fprintf(stderr,"请输入要发送的信息\n");
exit(1);
}
strcpy(buf,argv[1]);
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
printf("请输入用户名形如xxx--xxx\n");
printf("请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!\n");
printf("如果输入重复的用户名!请重新打开窗口!\n");
printf("请输入esc退出程序!\n");
Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
write(sockfd,buf,MAXLINE);
while (1) {
pid_t pid;
char *message;
int n;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
}
if (pid == 0) {
memset(buf,0,MAXLINE);
n = Read(sockfd, buf, MAXLINE);
if (n == 0)
{ printf("the servre has closed.\n");break; }
else
//Write(STDOUT_FILENO, buf, n);
printf("%s\n",buf);
printf("------------------------\n");
} else {
fgets(buf, MAXLINE, stdin);
if(memcmp(buf,"esc",3)==0)
{
exit(1);
}
Write(sockfd, buf, strlen(buf));
}
}
Close(sockfd);
return 0;
}
++++++++++++++++++++++++++++++++++++++++
[root@bogon ~]# gedit wrap.h
#include
#include
#include
void perr_exit(const char *s)
{
perror(s);
exit(1);
}
int Accept(int fd, struct sockaddr *sa, socklen_t * salenptr)
{
int n;
again:
if ((n = accept(fd, sa, salenptr)) < 0) {
if ((errno == ECONNABORTED) || (errno == EINTR))
goto again;
else
perr_exit("accept error");
}
return n;
}
void Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
if (bind(fd, sa, salen) < 0)
perr_exit("bind error");
}
void Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
if (connect(fd, sa, salen) < 0)
perr_exit("connect error");
}
void Listen(int fd, int backlog)
{
if (listen(fd, backlog) < 0)
perr_exit("listen error");
}
int Socket(int family, int type, int protocol)
{
int n;
if ((n = socket(family, type, protocol)) < 0)
perr_exit("socket error");
return n;
}
ssize_t Read(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
again:
if ((n = read(fd, ptr, nbytes)) == -1) {
if (errno == EINTR)
goto again;
else
return -1;
}
return n;
}
ssize_t Write(int fd, const void *ptr, size_t nbytes)
{
ssize_t n;
again:
if ((n = write(fd, ptr, nbytes)) == -1) {
if (errno == EINTR)
goto again;
else
return -1;
}
return n;
}
void Close(int fd)
{
if (close(fd) == -1)
perr_exit("close error");
}
ssize_t Readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0;
else
return -1;
} else if (nread == 0)
break;
nleft -= nread;
ptr += nread;
}
return n - nleft;
}
ssize_t Writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) <= 0) {
if (nwritten < 0 && errno == EINTR)
nwritten = 0;
else
return -1;
}
nleft -= nwritten;
ptr += nwritten;
}
return n;
}
static ssize_t my_read(int fd, char *ptr)
{
static int read_cnt;
static char *read_ptr;
static char read_buf[100];
if (read_cnt <= 0) {
again:
if ((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return -1;
} else if (read_cnt == 0)
return 0;
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return 1;
}
ssize_t Readline(int fd, void *vptr, size_t maxlen)
{
ssize_t n, rc;
char c, *ptr;
ptr = vptr;
for (n = 1; n < maxlen; n++) {
if ((rc = my_read(fd, &c)) == 1) {
*ptr++ = c;
if (c == '\n')
break;
} else if (rc == 0) {
*ptr = 0;
return n - 1;
} else
return -1;
}
*ptr = 0;
return n;
}
+++++++++++++++++++++++++++++
执行过程:
客户端一:[root@bogon select]# ./clie3 asd
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
asd--已登录!
------------------------
asd--已登录!
------------------------
qwe--已登录!
------------------------
asd--asdfsdfsdf //qwe给asd的信息
------------------------
qwe--asdfsdfdsf //发给qwe的信息
asd--已登录!
------------------------
qwe--已登录!
------------------------
zxc--已登录!
------------------------
asd--sadfdsf //zxc给asd的信息
------------------------
zxc--asdfdsf //回给zxc的信息
用户已登录!请重新打开窗口输入! // //将第四个重复的用户也广播出去!
客户端二:
[root@bogon select]# ./clie3 qwe
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
asd--已登录!
------------------------
qwe--已登录!
------------------------
asd--asdfsdfsdf 发给asd的信息
qwe--asdfsdfdsf asd 发给qwe的信息
------------------------
asd--已登录!
------------------------
qwe--已登录!
------------------------
zxc--已登录!
------------------------
用户已登录!请重新打开窗口输入! //将第四个重复的用户也广播出去!
------------------------
客户端三:
[root@bogon select]# ./clie3 zxc
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
asd--已登录!
------------------------
qwe--已登录!
------------------------
zxc--已登录!
------------------------
asd--sadfdsf
zxc--asdfdsf
------------------------
用户已登录!请重新打开窗口输入! // //将第四个重复的用户也广播出去!
------------------------
[root@bogon select]# ./clie3 asd //登录用户名重复!
请输入用户名形如xxx--xxx
请勿输入重复的用户名!发送信息时请输入要发送的用户名+您要输入的信息!
如果输入重复的用户名!请重新打开窗口!
请输入esc退出程序!
用户已登录!请重新打开窗口输入!
------------------------
0
上一篇:cu精英,csdn程序员和中华网愤青
下一篇:关于获取运营商的IP地址
相关热门文章
- test123
- 编写安全代码——小心有符号数...
- 使用openssl api进行加密解密...
- 一段自己打印自己的c程序...
- sql relay的c++接口
- linux dhcp peizhi roc
- 关于Unix文件的软链接
- 求教这个命令什么意思,我是新...
- sed -e "/grep/d" 是什么意思...
- 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
评论热议
0 0
- 冯伟浩 2012.6.5 C/S-单播
- 吴晓培 2012.6.21 C/S-单播-线程
- 单播,多播
- 单播&&多播
- 单播
- 107-使用多播的 UDP C/S 程序
- 单播,广播,组播
- 单播、广播、组播
- 单播,广播,组播
- 单播/组播/广播
- 广播 组播 单播
- 组播 广播 单播
- 单播、广播、组播
- 单播,广播,组播
- 单播、广播、组播
- 单播和多播
- 单播,广播,组播
- 广播,单播,组播
- 简单字符驱动程序mycdev.c
- C++ for循环执行顺序
- 简单字符驱动程序mycdev_globalmem.c
- cu精英,csdn程序员和中华网愤青
- Android中的Binder机制的简要理解一
- 冯伟浩 2012.6.5 C/S-单播
- 文章标题测试
- #1033 : 交错和
- Log4j使用总结以及配置
- 关于获取运营商的IP地址
- SVM 核函数的选择
- 用arp-scan扫描局域网IP地址
- Spring的IOC,AOP产生的原因
- linux sar用法大全
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
人偶系列
制作人偶
搪胶人偶
手指人偶
人偶商店
皮卡丘人偶
儿童人偶
小黄人 人偶
人偶馆绮幻夜攻略
人偶绮幻夜攻略
环保少女人偶被吊
人偶馆绮幻夜
人偶奇幻夜攻略
人偶馆奇幻夜攻略
人偶馆奇幻夜
人偶馆绮幻夜结局
人偶馆绮幻夜破解版
人偶馆绮幻夜破解
人偶馆绮幻夜走廊
人偶馆绮幻夜走廊怎么过
人偶馆绮幻夜事件分析
人偶相公完结全文阅读
人偶馆绮幻夜付费部分攻略
人偶馆绮幻夜第一关怎么过
你的人偶韩娱
人偶馆绮幻夜大白熊怎么过
人偶馆绮幻夜故事
怨灵宿舍之人偶老师
人偶总动员第四季
日本人偶娃娃
卡通人偶图片
人偶总动员全集
人偶总动员第二季
卡通衣服人偶道具
卡通行走人偶
卡通人偶制作
卡通人物人偶
球形关节人偶
卡通人偶衣服出租
超轻粘土人偶
无限之蔷薇人偶