服务端
// tcp/ip server七步走
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define NUM 1024//本服务器可以连接的最大客服端的个数
struct student
{
int id;
char a[20];
};
int main()
{
//1.创建socket socket()
fd_set fdset;//描述符集合
//int maxfd=-1;//最大文件描述符
//int cfd[NUM];//客服端文件描述符数组
int i,j;
//int count=0;//客服端数量
//char buf[1024];
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==sfd)perror("socket"),exit(-1);
printf("creat socket success\n");
//2.准备通信地址(服务器地址),使用结构体类型
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(10086);
addr.sin_addr.s_addr=inet_addr("192.168.1.5"); //client也用这个server的地址
//3.绑定socket和通信地址,使用bind()
int r=bind(sfd, (struct sockaddr*)&addr,sizeof(addr)); //client用connect
if(-1==r)
perror("bind"),exit(-1);
printf("bind success\n");
//4.生成侦听socket: listening socket listen() //client可没有这一步
r=listen(sfd,10);
if(-1==r)perror("listen"),exit(-1);
printf("listen success\n");
//5.响应客户端连接请求并生成connected socket accept() //client当然没有这一步
struct sockaddr_in recv_addr;
socklen_t len=sizeof(recv_addr);
int cfd=accept(sfd,(struct sockaddr*)&recv_addr,&len);
if(-1==cfd)
perror("accept"),exit(-1);
char* ip=inet_ntoa(recv_addr.sin_addr); //存储client的ip
printf("client$%s connect success\n",ip);
printf("客户端端口号:%d\n",recv_addr.sin_port);
/*while(1){
FD_ZERO(&fdset);
//把服务器描述符放入描述符号集合中。
if(sfd != -1){
FD_SET(sfd,&fdset);
maxfd = maxfd > sfd ? maxfd : sfd;
}
//把客户端描述符放入描述符号集合中。
for(i=0;i<count;i++){
if(cfd[i] != -1){
FD_SET(cfd[i],&fdset);
maxfd = maxfd > cfd[i] ? maxfd : cfd[i];
}
}
//监视描述符号集合
r = select(maxfd+1,&fdset,0,0,0);
if(r > 0) printf("监视到有动静!\n");
//如果有客户连接,就接收连接
if(sfd!=-1 && 1 == FD_ISSET(sfd,&fdset)){
cfd[count] = accept(sfd,0,0);
if(cfd[count] > 0){
printf("客户%d连接进来了!\n",cfd[count]);
count++;
}else{
printf("客户端%d退出连接!\n",cfd[i]);
close(cfd[i]);
cfd[i] = -1;
continue;
}
}
//如果客户端发数据,就接收并广播
for(i=0;i<count;i++){
//找到发数据的客户端
if(cfd[i] != -1 && 1 == FD_ISSET(cfd[i],&fdset) ){
//接收其发送的数据
r = read(cfd[i],buf,sizeof(buf)-1);
if(r > 0){
buf[r] = 0;
printf("%d:%s\n",cfd[i],buf);
//广播给所有连接上服务器的客户端
for(j=0;j<count;j++){
if(cfd[j] != -1)
write(cfd[j],buf,strlen(buf));
}
}else if(r == 0){
printf("网络异常,数据丢失!\n");
}else{
printf("网络异常\n");
}
}
}
}
}*/
//创建父子进程 进行通信
if(fork())
{
char sendbuf[1024]={0};
while(fgets(sendbuf,sizeof(sendbuf)-1,stdin)!=NULL)
{
write(cfd,sendbuf,sizeof(sendbuf)-1);
memset(sendbuf,0,sizeof(sendbuf)-1);
}
}
else
{
//接受客服端发过来的信息
char revbuf[1024]={0};
struct student stu;
read(cfd,&stu,sizeof(stu));
printf("客服端的id号为:%d %s\n",stu.id,stu.a);
//printf("客服端的姓名为:%s\n",stu.name);//存在一个乱码的问题
while(1)
{
int ret=read(cfd,revbuf,sizeof(revbuf)-1);
if(ret==0)
{
printf("客服端关闭连接\n");
exit(-1);
}
else if(ret<0)
{
printf("读取数据失败\n");
exit(-1);
}
fputs(revbuf,stdout);
memset(revbuf,0,sizeof(revbuf)-1);
}
}
close(cfd);
close(sfd);
return 0;
}
客户端
// tcp/ip server七步走
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
void handle(int num)
{
printf("%d\n",num);
exit(0);
}
struct student
{
int id;
char a[20];
};//结构体 用来发送id号给服务端
int main()
{
//1.创建socket socket()
signal(SIGUSR1,handle);
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==sockfd)
perror("socket"),exit(-1);
printf("creat socket success\n");
//2.准备通信地址(服务器地址),使用结构体类型
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(10086);
addr.sin_addr.s_addr=inet_addr("192.168.1.5");
int fd=connect(sockfd,(struct sockaddr*)&addr,sizeof(addr));
if(-1==fd)
printf("connect:%m\n");
if(fork())
{
while(1)
{
//接收数据
char revbuf[1024]={0};
int ret=read(sockfd,revbuf,sizeof(revbuf)-1);
if(ret==0)
{
printf("服务器关闭\n");
close(sockfd);
exit(-1);
}
else if(ret<0)
{
printf("接受数据:%m\n");
close(sockfd);
exit(-1);
}
fputs(revbuf,stdout);
memset(revbuf,0,sizeof(revbuf)-1);
}
close(sockfd);
kill(getpid(),SIGUSR1);//子进程收到服务器的关闭信息 杀死父进程
exit(0);
}
else
{
char sendbuf[1024]={0};
struct student stu;
stu.id=10;
strcpy(stu.a, "abcdefgh");
//stu.name="sun";
printf("发送给服务器本机信息\n");
write(sockfd,&stu,sizeof(stu));
while(fgets(sendbuf,sizeof(sendbuf)-1,stdin)!=NULL)//从键盘读入数据
{
write(sockfd,sendbuf,sizeof(sendbuf)-1);
memset(sendbuf,0,sizeof(sendbuf)-1);
}
}
close(sockfd);
return 0;
}