linux socket收发消息,linux socket实现网络聊天室(二):使用线程独立收发消息

一、引言

二、代码实现

1、服务器端

/*tcpserver.c 2011.9.1 by yyg*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MYPORT 3490 //定义端口

#define BACKLOG 10

#define MAXDATASIZE 1024

int sockfd,new_fd;

pthread_t accthread,recthread;

void recmessage(void){ //接收客户端信息函数

while(1){

int numbytes;

char buf[MAXDATASIZE];

if((numbytes = recv(new_fd,buf,MAXDATASIZE,0))==-1){

perror("recv");

exit(1);

}

buf[numbytes]='\0';

if(strcmp(buf,"exit")==0){ //若收到的是exit字符,则代表退出通信

printf("Client is closed\n");

close(new_fd);

close(sockfd);

exit(1);

}

printf("client:%s\n",buf);

}/*while*/

}

void acceptconnect(void){ //接受客户端连接请求函数

struct sockaddr_in their_addr;

int sin_size;

sin_size = sizeof(struct sockaddr_in);

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

perror("accept");

exit(1);

}

printf("server:got connection from %s\n",inet_ntoa(their_addr.sin_addr));

/*创建子线程,用于接收信息*/

if((pthread_create(&recthread,NULL,(void*)recmessage,NULL)) != 0){

printf("create thread error!\r\n");

exit(1);

}

}

int main(void){

struct sockaddr_in my_addr;

/*创建套接字*/

if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){

perror("socket");

exit(1);

}

/*初始化sockaddr_in结构体相关参数*/

my_addr.sin_family = AF_INET;

my_addr.sin_port = htons(MYPORT);

my_addr.sin_addr.s_addr = INADDR_ANY;

bzero(&(my_addr.sin_zero),8);

/*绑定端口与套接字*/

if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1){

perror("bind");

exit(1);

}

/*监听客户端套接字*/

if(listen(sockfd,BACKLOG)== -1){

perror("listen");

exit(1);

}

printf("listening...\n");

/*创建子线程,用于接收信息*/

if((pthread_create(&accthread,NULL,(void*)acceptconnect,NULL))!=0){

printf("create thread error!\n");

exit(1);

}

while(1){

char msg[MAXDATASIZE];

scanf("%s",msg);

if(send(new_fd,msg,strlen(msg),0) == -1){ //发送信息,与客户端交流

perror("send");

exit(1);

}

if(strcmp(msg,"exit") ==0){

printf("byebye\n");

close(new_fd);

close(sockfd);

exit(1);

}

}/*while*/

return 0;

}/*main*/

2.客户端

/*tcpclient.c 2010.9.1 by yyg*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT 3490

#define BACKLOG 10

#define MAXDATASIZE 1024

int sockfd;

pthread_t recthread;

/*接收信息函数*/

void recmessage(void){

while(1){

int numbytes;

char buf[MAXDATASIZE];

if((numbytes = recv(sockfd,buf,MAXDATASIZE,0))==-1){

perror("recv");

exit(1);

}

buf[numbytes]='\0';

if(strcmp(buf,"exit")==0){

printf("Server is closed\n");

close(sockfd);

exit(1);

}

printf("Server:%s\n",buf);

}/*while*/

}

int main(int argc,char *argv[]){

struct hostent *he;

struct sockaddr_in their_addr;

/*客户端输入方式:./client 172.31.100.236,若无输入后面IP地址,会提示错误*/

if(argc != 2){

fprintf(stderr,"usage:client hostname\n");

exit(1);

}

/*获取主机IP地址*/

if((he = gethostbyname(argv[1])) == NULL){

herror("gethostbyname");

exit(1);

}

/*创建套接字*/

if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){

perror("socket");

exit(1);

}

/*初始化sockaddr_in结构体*/

their_addr.sin_family = AF_INET;

their_addr.sin_port = htons(PORT);

their_addr.sin_addr = *((struct in_addr *)he->h_addr);

bzero(&(their_addr.sin_zero),8);

/*向服务器发送连接请求*/

if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1){

perror("connect");

exit(1);

}

/*创建子线程,用于接收信息*/

if((pthread_create(&recthread,NULL,(void*)recmessage,NULL))!= 0){

printf("create thread error!\r\n");

exit(1);

}

/*发送信息。接收发送信息用的是同一端口,都 是sockfd*/

while(1){

char msg[MAXDATASIZE];

scanf("%s",msg);

if(send(sockfd,msg,strlen(msg),0) == -1){

perror("send");

exit(1);

}

if(strcmp(msg,"exit") ==0){

printf("byebye\n");

close(sockfd);

exit(1);

}

}/*while*/

return 0;

}

运行结果:

终端1:

[root@localhost net]# ./tcpserver

server:got connection from 172.31.100.236

Hello,World!

client:hello

client:xiaolian

client:iou

ok

exit

byebye

终端2:

[root@localhost net]# ./tcpclient 172.31.100.236

Server:Hello,World!

hello

xiaolian iou

Server:ok

Server is closed

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值