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 <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;
}
#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;
}