TCP聊天程序linux,Linux网络编程之聊天程序(TCP协议之select)

服务器端:server.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXBUF 1024

int main(int argc, char **argv)

{

int sockfd, new_fd;

socklen_t len;

struct sockaddr_in my_addr, their_addr;

unsigned int myport, lisnum;

char buf[MAXBUF + 1];

fd_set rfds;

struct timeval tv;

int retval, maxfd = -1;

if (argv[2])

myport = atoi(argv[2]);      /* 将命令行字符串转换为整数。用于端口 */

else

myport = 8888;                           /* 设置默认端口 */

if (argv[3])

lisnum = atoi(argv[3]);                    /* 监听队列大小 */

else

lisnum = 2;

if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {            /* 创建socket对象 */

perror("socket");

exit(EXIT_FAILURE);

}

bzero(&my_addr, sizeof(my_addr));

my_addr.sin_family = PF_INET;                /* 地址协议 */

my_addr.sin_port = htons(myport);           /* 地址端口 */

if (argv[1])

my_addr.sin_addr.s_addr = inet_addr(argv[1]);

else

my_addr.sin_addr.s_addr = INADDR_ANY;                    /* 否则默认本机随意地址 */

if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) {/* 绑定地址信息 */

perror("bind");

exit(EXIT_FAILURE);

}

if (listen(sockfd, lisnum) == -1) {/* 监听网络 ,最大队列数是lisnum*/

perror("listen");

exit(EXIT_FAILURE);

}

while (1)

{

printf ("\n----wait for new connect\n");

len = sizeof(struct sockaddr);

if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1) {

/* 堵塞等待连接。连接成功返回新的socket描写叙述符,their_addr存储client的sockaddr 地址信息

perror("accept");

exit(errno);

} else

printf("server: got connection from %s, port %d, socket %d\n",

inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd);

while (1)

{

FD_ZERO(&rfds);     /* 清零rfds集合 */

FD_SET(0, &rfds);   /* 把标准输入加入rfds集合 */

FD_SET(new_fd, &rfds);                 /* 把new_fd加入rfds集合 */

maxfd = new_fd;

tv.tv_sec = 1;

tv.tv_usec = 0;

retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);    /* maxfd + 1监听的最大值加一 */

if (retval == -1)

{

perror("select");

exit(EXIT_FAILURE);

} else if (retval == 0) {

continue;

}

else

{

if (FD_ISSET(0, &rfds))                        /* 假设是标准输入可读 */

{

bzero(buf, MAXBUF + 1);

fgets(buf, MAXBUF, stdin);

if (!strncasecmp(buf, "quit", 4)) {

printf("i will quit!\n");

break;

}

len = send(new_fd, buf, strlen(buf) - 1, 0);

if (len > 0)

printf ("send successful,%d byte send!\n",len);

else {

printf("send failure!");

break;

}

}

if (FD_ISSET(new_fd, &rfds))           /* 假设是new_fd可读 */

{

bzero(buf, MAXBUF + 1);

len = recv(new_fd, buf, MAXBUF, 0);

if (len > 0)

printf ("recv success :‘%s‘,%dbyte recv\n", buf, len);

else

{

if (len < 0)

printf("recv failure\n");

else

{

printf("the ohter one end ,quit\n");

break;

}

}

}

}

}

close(new_fd);

printf("need othe connecdt (no->quit)");

fflush(stdout);

bzero(buf, MAXBUF + 1);

fgets(buf, MAXBUF, stdin);

if (!strncasecmp(buf, "no", 2))

{

printf("quit!\n");

break;

}

}

close(sockfd);

return 0;

}

客户端程序:client.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXBUF 1024

int main(int argc, char **argv)

{

int sockfd, len;

struct sockaddr_in dest;

char buffer[MAXBUF + 1];

fd_set rfds;

struct timeval tv;

int retval, maxfd = -1;

if (argc != 3)

{

printf("argv format errno,pls:\n\t\t%s IP port\n",argv[0], argv[0]);

exit(EXIT_FAILURE);

}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

{

perror("Socket");

exit(EXIT_FAILURE);

}

bzero(&dest, sizeof(dest));

dest.sin_family = AF_INET;

dest.sin_port = htons(atoi(argv[2]));

if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0)

{

perror(argv[1]);

exit(EXIT_FAILURE);

}

if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0)

{

perror("Connect ");

exit(EXIT_FAILURE);

}

printf("\nget ready pls chat\n");

while (1)

{

FD_ZERO(&rfds);

FD_SET(0, &rfds);

FD_SET(sockfd, &rfds);

maxfd = sockfd;

tv.tv_sec = 1;

tv.tv_usec = 0;

retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);

if (retval == -1)

{

printf("select %s", strerror(errno));

break;

}

else if (retval == 0)

continue;

else

{

if (FD_ISSET(sockfd, &rfds))

{

bzero(buffer, MAXBUF + 1);

len = recv(sockfd, buffer, MAXBUF, 0);

if (len > 0)

printf ("recv message:‘%s‘,%d byte recv\n",buffer, len);

else

{

if (len < 0)

printf ("message recv failure\n");

else

{

printf("the othe quit ,quit\n");

break;

}

}

}

if (FD_ISSET(0, &rfds))

{

bzero(buffer, MAXBUF + 1);

fgets(buffer, MAXBUF, stdin);

if (!strncasecmp(buffer, "quit", 4)) {

printf("i will quit\n");

break;

}

len = send(sockfd, buffer, strlen(buffer) - 1, 0);

if (len < 0) {

printf ("message send failure");

break;

} else

printf

("send success,%d byte send\n",len);

}

}

}

close(sockfd);

return 0;

}

測试方法例如以下:

gcc server.c -o server

gcc client.c -o client

./server 172.16.148.114  8888       /* 一个终端下。172.16.148.114是我虚拟机的IP地址*/

./client 172.16.148.114  8888      /*另外 一个终端下 */

select函数不会使用的參考这篇文章:http://blog.csdn.net/qq_21792169/article/details/50450360

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值