基于LInuxc语言TCP聊天服务端程序实现私聊,以及群聊和私聊的转换
?
//通過"@用戶名"實現單發,"->all"實現群發
?
//1net.h
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<pthread.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>
#include<sys/wait.h>
#include <arpa/inet.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<assert.h>
#include<time.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include<sys/un.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <pthread.h>
//127.0.0.1
#define SERVPORT 44432
#define BACKLOG 10
#define MAXDATASIZE 256
#define STDIN 0
#define COUNT 5
?
//2Server_multiple.c
#include "net.h"
int socket_fd[COUNT];
void pthread_function(int client_fd)
{
?? ?char message[1500];
?? ?char buf[1024];
?? ?int i,recvbytes;
?? ?char name[20];
?? ?recvbytes=recv(client_fd,name,20,0);
?? ?name[recvbytes]=':';
?? ?name[recvbytes]='\0';
?? ?while(1)
?? ?{
?? ??? ?if((recvbytes=recv(client_fd,buf,1024,0))==-1)
?? ??? ?{
?? ??? ??? ?perror("recv error\n");
?? ??? ??? ?exit(1);
?? ??? ?}
?? ??? ?if(recvbytes==0)
?? ??? ?{
?? ??? ??? ?printf("%s bye!(%sLeave the chat room)\n",name,name);
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?
?? ??? ?buf[recvbytes]='\0';
?? ??? ?for(i=0;i<COUNT;i++)
?? ??? ?{
?? ??? ??? ?if(socket_fd[i]==-1)
?? ??? ??? ?{
?? ??? ??? ??? ?continue;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?message[0]='\0';
?? ??? ??? ??? ?strcat(message,name);
?? ??? ??? ??? ?strcat(message,buf);
?? ??? ??? ??? ?if(send(socket_fd[i],message,strlen(message),0)==-1)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?perror("send error\n");
?? ??? ??? ??? ??? ?exit(1);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?close(client_fd);
?? ?for(i=0;i<COUNT;i++)
?? ?{
?? ??? ?if(socket_fd[i]==client_fd)
?? ??? ?{
?? ??? ??? ?socket_fd[i]=-1;
?? ??? ?}
?? ?}
?? ?pthread_exit(NULL);
}
int main(int argc, char* argv[])
{
?? ?int i;
?? ?for(i=0;i<COUNT;i++)
?? ?{
?? ??? ?socket_fd[i]=-1;
?? ?}
?? ?pthread_t id;
?? ?int sockfd,client_fd;
?? ?socklen_t sin_size;
?? ?struct sockaddr_in my_addr;
?? ?struct sockaddr_in remote_addr;
?? ?if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
?? ?{
?? ??? ?perror("socket");
?? ??? ?exit(1);
?? ?}
?? ?my_addr.sin_family=AF_INET;
?? ?my_addr.sin_port=htons(atoi(argv[2]));
?? ?my_addr.sin_addr.s_addr=inet_addr(argv[1]);
?? ?bzero(&(my_addr.sin_zero),8);
?? ?if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
?? ?{
?? ??? ?perror("bind false!\n");
?? ??? ?exit(1);
?? ?}
?? ?if(listen(sockfd,BACKLOG)==-1)
??????? {
?? ??? ?perror("listen false!\n");
?? ??? ?exit(1);
??????? }
??????? i=0;
??????? while(1)
??????? {
?????? ??? ?sin_size=sizeof(struct sockaddr_in);
?????? ??? ?if((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1)
?????? ??? ?{
?????? ??? ??? ?perror("accept error!\n");
?????? ??? ??? ?exit(1);
?????? ??? ?}
?????? ??? ?while(socket_fd[i]!=-1)
?????? ??? ?{
?????? ??? ??? ?i=(i+1)%COUNT;
?????? ??? ?}
?????? ??? ?socket_fd[i]=client_fd;
?????? ??? ?pthread_create(&id,NULL,(void *)pthread_function,(int *)(long)client_fd);//(int *)client_fd,修改成(int *)(long)client_fd(形參int* 是 8 字節,而實參 int client_fd卻是 4 字節。為了避免這個警告變為long int 型)
??????? }
}
?
//3Client_multiple.c
#include "net.h"
char recv_buf[1500],send_buf[1024];
char name[20];
void pthread_function(int sockfd)
{
?? ?int recvbytes;
?? ?while(1)
?? ?{
?? ??? ?if((recvbytes=recv(sockfd,recv_buf,1500,0))==-1)
?? ??? ?{
?? ??? ??? ?perror("recv error\n");
?? ??? ??? ?exit(1);
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?recv_buf[recvbytes]='\0';
?? ??? ??? ?char *x,*y;
?? ??? ??? ?x=strstr(recv_buf,"@");
?? ??? ??? ?y=strstr(recv_buf,"->all");
?? ??? ??? ?int flag=1;
?? ??? ??? ?if(x!=NULL)
?? ??? ??? ?{
?? ??? ??? ??? ?x=strcat(x,":");
?? ??? ??? ??? ?flag=strcmp(x+1,name);
?? ??? ??? ??? ?if(!flag)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?recv_buf[recvbytes]='\0';
?? ??? ??? ??? ??? ?printf("%s\n",recv_buf);
?? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?
?? ??? ??? ?}
?? ??? ??? ?else if(y!=NULL)
?? ??? ??? ?{
?? ??? ??? ??? ?flag=strcmp(y,"->all");
?? ??? ??? ??? ?recv_buf[recvbytes-5]='\0';
?? ??? ??? ??? ?printf("%s\n",recv_buf);
?? ??? ??? ?}
?? ??? ??? ?else;
?? ??? ?}
?? ?}
}
int main(int argc, char* argv[])
{
?? ?pthread_t id;
?? ?int sockfd;
?? ?struct sockaddr_in server_addr;
?? ?server_addr.sin_family=AF_INET;
?? ?server_addr.sin_port=htons(atoi(argv[2]));
?? ?server_addr.sin_addr.s_addr=inet_addr(argv[1]);//127.0.0.1
?? ?if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
?? ?{
?? ??? ?perror("socket error\n");
?? ??? ?exit(1);
?? ?}
?? ?if(connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1)
?? ?{
?? ??? ?perror("connect error\n");
?? ??? ?exit(1);
?? ?}
?? ?printf("input your name:");
?? ?scanf("%s",name);
?? ?strcat(name,":");
?? ?send(sockfd,name,strlen(name),0);
?? ?pthread_create(&id,NULL,(void *)pthread_function,(int *)(long)sockfd);//(int *)client_fd,修改成(int *)(long)client_fd(形參int* 是 8 字節,而實參 int client_fd卻是 4 字節。為了避免這個警告變為long int 型)
?? ?while(1)
?? ?{
?? ??? ?gets(send_buf);
?? ??? ?if(send(sockfd,send_buf,strlen(send_buf),0)==-1)
?? ??? ?{
?? ??? ??? ?perror("send error\n");
?? ??? ??? ?exit(1);
?? ??? ?}
?? ??? ?sleep(1);
?? ?}
?? ?close(sockfd);
?? ?pthread_cancel(id);
?? ?return 0;?? ?
}
參考Linux程序設計第三版(金..)
?
總結
以上是生活随笔為你收集整理的基于LInuxc语言TCP聊天服务端程序实现私聊,以及群聊和私聊的转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: KITTI数据集(全)百度网盘下载地址
- 下一篇: docker部署svnadmin进行权限