套接字编程实现多客户端间通讯(TCP/IP)
链接数据库:
mysql -u root -p513920; create database member; use member;
create table person(id int primary key auto_increment,name char(20) not null, passwd char(20) default '513920');
insert into person(id,name) values(1000,"zhangsan");
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef __LINK_H__ 2 #define __LINK_H__ 3 #include<sys/socket.h> 4 #include<sys/types.h> 5 #include<stdio.h> 6 #include<netinet/in.h> 7 #include<arpa/inet.h> 8 #include<errno.h> 9 #include<string.h> 10 #include<stdlib.h> 11 #include<unistd.h> 12 #include<pthread.h> 13 14 struct DATA 15 { 16 int type; 17 int flag; 18 int id; 19 char name[20]; 20 char passwd[20]; 21 int confd; 22 23 struct sockaddr_in caddr; 24 }; 25 26 typedef struct online 27 { 28 struct DATA data; 29 struct online *next; 30 }Men,*Pmen;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include"link.h" 2 void add_node(int confd,int id,struct sockaddr_in caddr) 3 { 4 Pmen temp=(Pmen)malloc(sizeof(Men)); 5 temp->data.id=id; 6 temp->data.confd=confd; 7 temp->data.caddr=caddr; 8 temp->next=head; 9 head=temp; 10 return ; 11 } 12 13 void show_link() 14 { 15 Pmen p=head; 16 printf("id\tconfd\tport\taddr\n"); 17 char addr[20]; 18 while(p!=NULL) 19 { 20 printf("%d\t%d\t%d\t%s\n",p->data.id,p->data.confd,\ 21 ntohs(p->data.caddr.sin_port),\ 22 inet_ntop(AF_INET,&(p>data.caddr.sin_addr.s_addr),addr,sizeof(addr))); 23 p=p->next; 24 } 25 } 26 27 void delete_node(int confd) 28 { 29 Pmen p=NULL; 30 if(head->data.confd==confd && head->next==NULL) 31 { 32 free(head); 33 head=NULL; 34 return ; 35 } 36 else if(head->data.confd==confd && head->next!=NULL 37 { 38 p=head->next; 39 free(head); 40 head=p; 41 return ; 42 } 43 p=head; 44 45 Pmen q=NULL; 46 while(p->next!=NULL) 47 { 48 if(p->next->data.confd==confd) 49 { 50 q=p->next; 51 p->next=q->next; 52 free(q); 53 return ; 54 } 55 p=p->next; 56 } 57 printf("该节点不存在\n"); 58 return ; 59 } 60 61 int search_confd(int id) 62 { 63 Pmen p=head; 64 while(p!=NULL) 65 { 66 if(p->data.id==id) 67 return p->data.confd; 68 p=p->next; 69 } 70 return -1; 71 }
服务器端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<mysql/mysql.h> 2 #include"link.h" 3 4 struct DATA login(struct DATA temp) 5 { 6 MYSQL *conn; 7 conn=mysql_init(NULL); 8 if(!mysql_real_connect(conn,"localhost","root","513920","member",0,NULL,0)) 9 { 10 printf("connect mysql error\n"); 11 temp.flag=-1; 12 return temp; 13 } 14 char buf[100]; 15 sprintf(buf,"select * from person where id=%d and passwd=\'%s\'",temp.id,temp.p 16 asswd); 17 printf("%s\n",buf); 18 if(mysql_query(conn,buf)) 19 { 20 printf("mysql_query error\n"); 21 temp.flag=-1; 22 return temp; 23 } 24 MYSQL_RES *res; 25 MYSQL_ROW row; 26 27 res=mysql_use_result(conn); 28 row=mysql_fetch_row(res); 29 if(row==NULL) 30 { 31 temp.flag=-1; 32 printf("the person is not exist\n"); 33 return temp; 34 } 35 temp.flag=1; 36 strcpy(temp.name,row[1]); 37 mysql_free_result(res); 38 mysql_close(conn); 39 return temp; 40 } 41 struct DATA person_register(struct DATA temp) 42 { 43 MYSQL *conn; 44 conn=mysql_init(NULL); 45 if(!mysql_real_connect(conn,"localhost","root","513920","member",0,NULL,0)) 46 { 47 printf("connect mysql error\n"); 48 temp.flag=-1; 49 return temp; 50 } 51 char buf[100]; 52 sprintf(buf,"insert into person(name,passwd) values(\'%s\',\'%s\')",temp.name, 53 temp.passwd); 54 if(mysql_query(conn,buf)) 55 { 56 printf("mysql_query error\n"); 57 temp.flag=-1; 58 return temp; 59 } 60 61 62 if(mysql_query(conn,"select max(id) as value from person")) 63 { 64 printf("mysql_query select id error\n"); 65 temp.flag=-1; 66 return temp; 67 } 68 MYSQL_RES *res; 69 MYSQL_ROW row; 70 71 res=mysql_use_result(conn); 72 row=mysql_fetch_row(res); 73 if(row==NULL) 74 { 75 temp.flag=-1; 76 printf("the person is not exist\n"); 77 return temp; 78 } 79 80 temp.flag=1; 81 temp.id=atoi(row[0]); 82 mysql_free_result(res); 83 mysql_close(conn); 84 return temp; 85 } 86 87 void * fun(void *arg) 88 { 89 int confd=*((int *)arg); 90 int ret; 91 struct message mb; 92 int sendfd; 93 while(1) 94 { 95 ret=read(confd,&mb,sizeof(mb)); 96 if(ret<=0) 97 { 98 delete_node(confd); 99 close(confd); 100 return NULL; 101 } 102 sendfd=search_confd(mb.id); 103 if(sendfd<0) 104 continue; 105 else 106 write(sendfd,mb.buf,strlen(mb.buf)+1); 107 } 108 } 109 110 int main() 111 { 112 head=NULL; 113 int listenfd; 114 listenfd=socket(AF_INET,SOCK_STREAM,0); 115 printf("listenfd=%d\n",listenfd); 116 117 //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 118 struct sockaddr_in myaddr; 119 myaddr.sin_family=AF_INET; 120 myaddr.sin_port=htons(7319); 121 inet_pton(AF_INET,"192.168.6.11",&myaddr.sin_addr.s_addr); 122 123 int ret=bind(listenfd,(struct sockaddr *)&myaddr,sizeof(myaddr)); 124 if(ret<0) 125 { 126 perror("bind failed:"); 127 exit(0); 128 } 129 //int listen(int sockfd, int backlog); 130 ret=listen(listenfd,20); 131 if(ret<0) 132 { 133 perror("listen failed:"); 134 exit(0); 135 } 136 137 //int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 138 139 struct sockaddr_in caddr; 140 int len=sizeof(caddr); 141 int confd; 142 int id; 143 struct DATA temp; 144 while(1) 145 { 146 confd=accept(listenfd,(struct sockaddr*)&caddr,&len); 147 if(confd<0) 148 { 149 perror("accept failed:"); 150 exit(0); 151 } 152 ret=read(confd,&temp,sizeof(temp)); 153 if(ret<=0) 154 { 155 close(confd); 156 continue; 157 } 158 switch(temp.type) 159 { 160 case 1: 161 temp=login(temp); 162 break; 163 case 2: 164 temp=person_register(temp); 165 break; 166 default: 167 close(confd); 168 continue; 169 } 170 printf("%d\n",temp.flag); 171 ret=write(confd,&temp,sizeof(temp)); 172 if(ret<=0) 173 continue; 174 if(temp.flag==-1) 175 { 176 continue; 177 } 178 add_node(confd,temp.id,caddr); 179 show_link(); 180 181 pthread_t pid; 182 pthread_create(&pid,NULL,fun,&confd); 183 } 184 }
客户端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<sys/socket.h> 2 #include<sys/types.h> 3 #include<stdio.h> 4 #include<netinet/in.h> 5 #include<arpa/inet.h> 6 #include<errno.h> 7 #include<string.h> 8 #include<stdlib.h> 9 #include<unistd.h> 10 #include"link.h" 11 12 void login(int sockfd); 13 void menu(int sockfd); 14 15 void login(int sockfd) 16 { 17 struct DATA temp; 18 printf("请输入id:"); 19 scanf("%d",&temp.id); 20 printf("请输入passwd:"); 21 scanf("%s",temp.passwd); 22 temp.type=1; 23 int ret=write(sockfd,&temp,sizeof(temp));//将登录信息写给服务器 24 if(ret<=0) 25 { 26 printf("write error\n"); 27 close(sockfd); 28 exit(0); 29 } 30 ret=read(sockfd,&temp,sizeof(temp)); 31 if(ret<=0 || ret!=sizeof(temp)) 32 { 33 printf("read login pack error\n"); 34 close(sockfd); 35 exit(0); 36 } 37 if(temp.flag!=1) 38 { 39 printf("用户名或者密码错误\n"); 40 close(sockfd); 41 exit(0); 42 } 43 printf("欢迎%s登录\n",temp.name); 44 } 45 46 void person_register(int sockfd) 47 { 48 struct DATA temp; 49 printf("请输入name:"); 50 scanf("%s",temp.name); 51 printf("请输入passwd:"); 52 scanf("%s",temp.passwd); 53 temp.type=2; 54 int ret=write(sockfd,&temp,sizeof(temp));//将登录信息写给服务器 55 if(ret<=0) 56 { 57 printf("write error\n"); 58 close(sockfd); 59 exit(0); 60 } 61 ret=read(sockfd,&temp,sizeof(temp)); 62 if(ret<=0 || ret!=sizeof(temp)) 63 { 64 printf("read login pack error\n"); 65 close(sockfd); 66 exit(0); 67 } 68 if(temp.flag!=1) 69 { 70 printf("注册失败\n"); 71 close(sockfd); 72 exit(0); 73 } 74 printf("注册成功 id----%d\n",temp.id); 75 } 76 77 void menu(int sockfd) 78 { 79 system("clear"); 80 printf("***************\n"); 81 printf("* 0 exit *\n"); 82 printf("* 1 login *\n"); 83 printf("* 2 register *\n"); 84 printf("***************\n"); 85 int key; 86 printf("please input your chioce:"); 87 scanf("%d",&key); 88 89 switch(key) 90 { 91 case 1: 92 login(sockfd); 93 break; 94 case 2: person_register(sockfd); 95 break; 96 case 0: 97 exit(0); 98 break; 99 default: 100 printf("error input\n"); 101 } 102 } 103 104 int main() 105 { 106 //int socket(int domain, int type, int protocol); 107 int sockfd; 108 sockfd=socket(AF_INET,SOCK_STREAM,0); 109 printf("sockfd=%d\n",sockfd); 110 111 //int connect(int sockfd, struct sockaddr *serv_addr, int addrlen ); 112 struct sockaddr_in seraddr; 113 seraddr.sin_family=AF_INET; 114 seraddr.sin_port=htons(7319); 115 inet_pton(AF_INET,"192.168.6.11",&seraddr.sin_addr.s_addr); 116 int ret=connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr)); 117 if(ret<0) 118 { 119 perror("connect failed:"); 120 exit(0); 121 } 122 menu(sockfd); 123 struct message mb; 124 pid_t pid; 125 pid=fork(); 126 if(pid>0) 127 { 128 while(1) 129 { 130 printf("请输入你要发送的id和数据(1001-yisheng):"); 131 scanf("%d-%s",&mb.id,mb.buf); 132 write(sockfd,&mb,sizeof(mb)); 133 } 134 } 135 else if (pid==0) 136 { 137 while(1) 138 { 139 read(sockfd,mb.buf,20); 140 printf("read buf=%s\n",mb.buf); 141 } 142 } 143 close(sockfd); 144 return 0; 145 }
make一下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ALL: 2 gcc link.c server.c -o server -lpthread -lmysqlclient 3 gcc link.c client.c -o client 4 clean: 5 rm -rf client server
效果如下: