C语言网络编程:客户端与服务端最简单的通信模型

服务端和客户端

如果你是小白或者是非计算机专业的人可能对这两个词比较陌生,我们通常所说的服务端就为我们提供服务的主机,客户端你可以理解为你自己的电脑。在这里举一个例子。你用百度网盘下载一个东西,首先你得向百度网盘的服务器发送一个请求,然后建立连接,然后它再把数据发送给你。做一个过程你是客户端,百度网盘服务器是服务端,它为你提供了下载资料的服务。从我们发送下载请求,到它把资料发送给我们,这就是客户端与服务端的一次完整的通信。今天我们就来写一篇最简单的服务端和客户端的模型。

客户端实现

#include<stdio.h>
 #include<stdlib.h>
 #include<string.h>
 #include<unistd.h>
 #include<sys/types.h>
 #include<sys/socket.h>
 #include<arpa/inet.h>
 int main ()
{
//创建套接字
 int sockfd=socket(AF_INET,SOCK_STREAM,0);
 struct sockaddr_in seraddr;
 seraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
 seraddr.sin_port=htons(65123);
 seraddr.sin_family=AF_INET;
 int res=connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
 char buf[1024];
 for(;;)
 {
 bzero(buf,sizeof(buf));
 printf("请输入要转换的字符串:");
 scanf("%s",buf);
 while(getchar()!='\n');
 //把数据发送到服务端
 write(sockfd,buf,strlen(buf));

 bzero(buf,sizeof(buf));
 //从服务端读取数据
 read(sockfd,buf,sizeof(buf));
 printf("转化后的字符:%s\n",buf);
 }
 }
      

我们实现一个由客户端对服务端发送一个大小写转换功能的一个请求,然后我们输入一串字符串,发送到服务器,服务器接收后给我们返回来转化好的字符串。

服务端的实现

#include<stdio.h>                                                      
#include<stdlib.h>
#include<string.h>
#include<strings.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<signal.h>
void func(char *str) //大小写转化函数
{
for(int i=0;i<strlen(str);i++)
{
     if(str[i]>='a'&&str[i]<='z')
     {
      str[i]-=32;
     }
     else if(str[i]>='A'&&str[i]<='Z')
     {
      str[i]+=32;
     }
}
}
//创建套接字函数
int get_sockfd(const char *ip, int port)
{
   struct sockaddr_in seraddr;
   int sockfd=socket(AF_INET,SOCK_STREAM,0);
   seraddr.sin_family=AF_INET;
   seraddr.sin_port=htons(port);
   //seraddr.sin_adde=inet_addr(ip);;
   inet_pton(AF_INET,ip,&(seraddr.sin_addr.s_addr));
   int res=bind(sockfd,(struct sockaddr * )&seraddr,sizeof(seraddr));
   res=listen(sockfd,20);
   return sockfd;
}
void function(int sufnum)
{
printf("get SIGPIPE\n");
}
int main()
{
char buf[1024];
struct sockaddr_in  cliaddr;
socklen_t clien =sizeof(cliaddr);
signal(SIGPIPE ,function);
int sockfd=get_sockfd("0.0.0.0",65123);
for (;;)
{
   int cfd=accept(sockfd,(struct sockaddr *)&cliaddr,&clien);
   char ip[32];
   int port;

   port=ntohs(cliaddr.sin_port);
   inet_ntop(AF_INET,&(cliaddr.sin_addr.s_addr),ip, sizeof(cliaddr));
   printf("[%s][%d]\n",ip,port);
   pid_t pid=fork();
   if(pid==0)
   {
   for(;;)
   {
     bzero(buf,sizeof(buf));
     int res=read(cfd,buf,sizeof(buf));
     printf("read res:%d\n",res);
     if(res==0)
     {
       printf("掉线!!!!\n");
       close(cfd);
       exit(-1);
     }
     printf("接收到字符串:%s\n",buf);
     func(buf);
     //处理好的字符串发送给客户端
     write(cfd,buf,strlen(buf));
   }
   }                                                               
   close(cfd);
}


测试

我们可以看到结果的显示,我们在客户端输入的字符串被服务端成功地接收并做了相应的转换处理然后再发送给我们客户端。

整个通信原理图和函数

涉及到的各种函数读者有兴趣可以自行去了解,后期我也会更新相关的函数讲解。