CS架构:
第一种:实现一个服务端,多个客户端,能实现客户端与服务端的交互:tcp-fork
Server:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int serverfd;
int clientfd;
int ret;
// 1 、创建一个socket
serverfd = socket(AF_INET,SOCK_STREAM,0);
if(serverfd < 0)
{
perror("socket create fail");
return -1;
}
int reuse = 1;
ret = setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
printf("setsockopt ret=%d\n",ret);
struct sockaddr_in serveraddr;
struct sockaddr_in clientaddr;
memset(&serveraddr,0,sizeof(serveraddr));
memset(&clientaddr,0,sizeof(clientaddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY; //表示接受任意ip的请求
serveraddr.sin_port = htons(8000); //表示对应的端口号,客户端就可以通过这个端口进行通讯
// 2、绑定我们的地址和端口号,先初始化这个地址
ret = bind(serverfd,(struct sockaddr * )&serveraddr,sizeof(struct sockaddr_in));
if(ret < 0)
{
perror("bind fail");
close(serverfd);
return -1;
}
// 3、监听,是否有连接请求。
ret = listen(serverfd,10);
if(ret < 0)
{
perror("listen fail");
close(serverfd);
return -1;
}
while(1)
{
int cfd;
int sin_size = sizeof(struct sockaddr_in);
// 4 、接受新连接请求。
cfd = accept(serverfd, (struct sockaddr *)&clientaddr, &sin_size);
printf("New connection fd=%d IP:PORT [%s:%hu]\n",cfd,inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
if(cfd < 0)
{
perror("accept fail");
close(cfd);
continue;
}
char buf[128];
memset(buf,0,128);
// 启动子进程去处理,新连接的请求
pid_t pid = fork();
if(pid > 0)
{
//父进程返回,继续接收新的连接请求。
// close(cfd);
continue;
}else if(pid == 0)
{
//子进程处理客户端发过来的数据,并且将其发过来的数据,再发送给客户端
//5、对数据做收发处理。
close(serverfd);
read(cfd,buf,128);
write(cfd,buf,128);
close(cfd);
exit(0);
}
}
//6、关闭对应的fd。
close(serverfd);
close(clientfd);
}
Client:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
int main()
{
int clientfd;
int ret;
// 1、新建一个socket
clientfd = socket(AF_INET,SOCK_STREAM,0);
if(clientfd < 0)
{
perror("create socket fail");
return -1;
}
struct sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr));
//设置好对应的服务器的地址和端口号
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("192.168.5.3");
serveraddr.sin_port = htons(8000);
// 2、连接服务器,如果连接成功的话,就可以实现通讯了。
ret = connect(clientfd,(struct sockaddr *)&serveraddr, sizeof(struct sockaddr) );
if(ret < 0)
{
perror("connect fail \n");
close(clientfd);
return -1;
}
char buf[128];
memset(buf,0,128);
//3、实现数据的收发。
// while(1)
{
printf("Please input a string: ");
scanf("%s",buf);
send(clientfd,buf,strlen(buf),0);
printf("Recv from server:");
recv(clientfd,buf,128,0);
printf("\n %s \n",buf);
memset(buf,0,128);
}
// 4、关闭连接。
close(clientfd);
}
第二种:实现一服务端,多客户端,客户端与客户端间的交互,通过服务端转:
客户端思路
服务端思路:
tcp-pthread
server:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
struct UsrInfo{
pthread_t tid;
int fd;
int uid;
}usrinfo[10];
void *func(void *arg)
{
int i = (int)arg;
int j;
pthread_detach( pthread_self() );
char buf[128];
while(1)
{
int sendto;
char sendbuf[128];
bzero(sendbuf,128);
if(recv(usrinfo[i].fd,buf,128,0) <= 0)
{
close(usrinfo[i].fd);
usrinfo[i].fd = 0;
break;
}
printf("222====\n");
sscanf(buf,"%d %s",&sendto,sendbuf);
for(j=0;j<10;j++)
{
if(usrinfo[j].uid == sendto )
{
write(usrinfo[j].fd,sendbuf,128);
break;
}
}
if(j==10)
printf("sorry ,there is no user\n");
}
printf("client has closed\n");
pthread_exit(NULL);
}
int main()
{
int serverfd;
int clientfd;
int ret;
int val = 1;
// 1 、创建一个socket
serverfd = socket(AF_INET,SOCK_STREAM,0);
if(serverfd < 0)
{
perror("socket create fail");
return -1;
}
ret = setsockopt(serverfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(int));
struct sockaddr_in serveraddr;
struct sockaddr_in clientaddr;
memset(&serveraddr,0,sizeof(serveraddr));
memset(&clientaddr,0,sizeof(clientaddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY; //表示接受任意ip的请求
serveraddr.sin_port = htons(8000); //表示对应的端口号,客户端就可以通过这个端口进行通讯
// 2、绑定我们的地址和端口号,先初始化这个地址
ret = bind(serverfd,(struct sockaddr * )&serveraddr,sizeof(struct sockaddr_in));
if(ret < 0)
{
perror("bind fail");
close(serverfd);
return -1;
}
// 3、监听,是否有连接请求。
ret = listen(serverfd,10);
if(ret < 0)
{
perror("listen fail");
close(serverfd);
return -1;
}
int sin_size = sizeof(struct sockaddr_in);
while(1)
{
int i;
for(i=0;i<10;i++)
{
if( usrinfo[i].fd == 0 )
break;
}
// 4 、接受连接请求。
usrinfo[i].fd = accept(serverfd, (struct sockaddr *)&clientaddr, &sin_size);
if(usrinfo[i].fd < 0)
{
perror("accept fail");
continue;
}
int id;
//记录客户端的ID
read(usrinfo[i].fd,&usrinfo[i].uid,4);
printf("New connection: fd=%d uid=%d\n",usrinfo[i].fd,usrinfo[i].uid);
pthread_create(&usrinfo[i].tid,NULL,func,(void *)i);
}
//6、关闭对应的fd。
close(serverfd);
close(clientfd);
}
Client1: ID为123(第二个客户端可以设成456)
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
void *readfunc(void *arg)
{
pthread_detach(pthread_self());
char buf[128];
int fd = (int)arg;
while(1)
{
bzero(buf,128);
if(read(fd,buf,128) == 0)
{
printf("server has closed\n");
break;
}
printf("Recv from server :%s\n",buf);
}
pthread_exit(NULL);
}
int main()
{
int clientfd;
int ret;
// 1、新建一个socket
clientfd = socket(AF_INET,SOCK_STREAM,0);
if(clientfd < 0)
{
perror("create socket fail");
return -1;
}
struct sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr));
//设置好对应的服务器的地址和端口号
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("192.168.5.3");
serveraddr.sin_port = htons(8000);
// 2、连接服务器,如果连接成功的话,就可以实现通讯了。
ret = connect(clientfd,(struct sockaddr *)&serveraddr, sizeof(struct sockaddr) );
if(ret < 0)
{
perror("connect fail \n");
close(clientfd);
return -1;
}
//用户的id,自己定义一个,对于不同的用户,定义不同的ID
int id=123;
write(clientfd,&id,4);
char buf[128];
memset(buf,0,128);
pthread_t pid;
pthread_create(&pid,NULL,readfunc,(void *)clientfd);
//3、实现数据的收发。
while(1)
{
memset(buf,0,128);
printf("Please input a string: ");
scanf("%s",buf);
write(clientfd,buf,strlen(buf));
if( strcmp(buf,"quit") == 0)
break;
}
printf("连接已断开\n");
// 4、关闭连接。
close(clientfd);
}