TCP服务器客户端网络通信

本文通过打电话的比喻,详细解析了TCP通信中服务器与客户端的工作流程。包括创建套接字、绑定地址信息、监听连接请求等步骤,并提供了具体的C语言代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP的服务器和客户端
  服务器:提供服务的一方  ---- 被动的一方
  客户端:请求服务的一方  ---- 主动的一方
  Socket服务器客户端网络通信

下面用一个简单的例子来说明一下服务器与客户端的通信流程。 

举例:打电话
 
  等待接听电话的一方:                                                            流程实现函数

                                               
  1、得到一个手机                                                    -------- 创建套接字(socket)
  2、申请电话号码,并将该电话号码与手机绑定     -------- 绑定地址信息(bind)---ip地址和端口号
  3、等待接听电话                                                    -------- 创建一个监听队列(listen)
  4、接电话                                                               -------- 接受连接请求(accept)
  5、聊天                                                                  -------- 收发消息(send/recv)
  6、挂电话                                                              -------- 关闭套接字(close)
  
 
  打电话的一方:
  1、得到一个手机                                                    -------- 创建套接字(socket)
  2、申请电话号码,并将该电话号码与手机绑定     -------- 绑定地址信息(bind)---ip地址和端口号(可选)
  3、拨打电话                                                           -------- 发起连接请求(connect)
  4、聊天                                                                   -------- 收发消息(send/recv)
  5、挂电话                                                               -------- 关闭套接字(close)
 
 
 


  服务器接收客户端的消息,当客户端(close)退出时,服务器中的recv就会返回0


  
  注意:服务器端  socket的返回值为一个主动的套接字,listen之后,该套接字就会变成一个被动等待连接的监听套接字, 所谓的监听套接字:该套接字只能用于等待客户端的连接。
  
  但是:服务器要和客户端通信,也需要套接字,所以accept执行成功后,会返回 一个套接字描述符,该套接字是专门用来和客户端通信的。

客户端服务器代码实现:


服务器代码实现如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>

int main()
{
   
intsocket_fd=socket(PF_INET,SOCK_STREAM,0);
   
if(socket_fd<0)
   
{
       
perror("socket error!");
       
return-1;
   
}

   
structsockaddr_insocket_addr;
    memset(&socket_addr,0,sizeof(socket_addr));
   
socket_addr.sin_family=PF_INET;
   
socket_addr.sin_port=htons(9999);
   
socket_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
   
intret=bind(socket_fd,(structsockaddr*)&socket_addr,sizeof(socket_addr));
   
if(ret<0)
   
{
       
perror("bind error!");
       
close(socket_fd);
       
return-1;
   
}

   
ret=listen(socket_fd,10);
   
if(ret<0)
   
{
       
perror("listen error!");
       
close(socket_fd);
       
return-1;
   
}
   
printf("listening...\n");  
   
intconnect_fd=accept(socket_fd,NULL,NULL);
   
if(connect_fd<0)
   
{
       
perror("accept error!");
       
close(socket_fd);
       
return-1;
   
}

   
charbuf[1024]={0};
   
while(1)
   
{
       
ssize_tsize=recv(connect_fd,buf,sizeof(buf),0);
       
if(0==size)
       
{
           
break;
       
}
       
if(size<0)
       
{
           
perror("recv error!");
           
close(socket_fd);
           
close(connect_fd);
           
return-1;
       
}
       
printf("receive data:%s\n",buf);
       
memset(buf,0,sizeof(buf));
       
printf("server:\n");
       
gets(buf);
       
size=send(connect_fd,buf,sizeof(buf),0);   
       
if(size<0)
       
{
           
perror("send error!");
           
close(socket_fd);
           
close(connect_fd);
           
return-1;
       
}
   
}
   
close(socket_fd);
   
close(connect_fd);
   
return0;
}


客户端代码实现如下:


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

intmain()
{
   
intclient_fd=socket(PF_INET,SOCK_STREAM,0);
   
if(client_fd<0)
   
{
       
perror("socket error!");
       
return-1;
   
}

   
structsockaddr_insocket_addr;
   
memset(&socket_addr,0,sizeof(socket_addr));
   
socket_addr.sin_family=PF_INET;
   
socket_addr.sin_port=htons(9999);
   
socket_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
   
intret=connect(client_fd,(structsockaddr*)&socket_addr,sizeof(socket_addr));
   
if(ret<0)
   
{
       
perror("connect error!");
       
close(client_fd);
       
return-1;
   
}

   
charbuf[1024]={0};
   
while(1)
   
{
       
memset(buf,0,sizeof(buf));
       
printf("client:\n");
       
gets(buf);
       
if(strcmp(buf,"quit")==0)
           
break;
       
ret=send(client_fd,buf,sizeof(buf),0);
       
if(ret<0)
       
{
           
perror("send error!");
           
close(client_fd);
           
return-1;
       
}
       
printf("send ok\n");
       
memset(buf,0,sizeof(buf));
       
ret=recv(client_fd,buf,sizeof(buf),0);
       
if(0==ret)
       
{
           
close(client_fd);
           
break;
       
}
       
if(ret<0)
       
{
           
perror("recv error!");
           
close(client_fd);
           
return-1;
       
}
       
printf("data from server:%s\n",buf);
   
}
   
close(client_fd);
   
return0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值