首先,socket主要是提供了不同主机进程间数据通信的机制;
在了解socket通信之前,首先了解一下TCP协议的三次握手原理,可以概括为如下图所示;
个人理解三次握手的意义在于验证客户端与服务器收发功能是否正常,第一次握手:客户端发送网络包,服务端收到了、第二次握手:服务端发包,客户端收到了、第三次握手:客户端发包,服务端收到了、这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
实现服务器于客户端之间的通信流程可以概括如下图所示:
按照流程服务器(server.cpp)的代码如下:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define myport 319
char buf[200];
int main()
//int main(int argc,char*argv[])
{
//socket
int sockfd,new_sockfd;
struct sockaddr_in sin_addr,pin_addr;
int len,pin_addr_size,i;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
{
printf("can't create socket\n");
exit(1);
}
//bind
memset(&sin_addr,0,sizeof(sin_addr));
sin_addr.sin_family=AF_INET;
sin_addr.sin_addr.s_addr=htonl(INADDR_ANY);
sin_addr.sin_port=htons(myport);
if(bind(sockfd,(struct sockaddr*)&sin_addr,sizeof(sin_addr))<0)
{
perror("bind");
printf("can't bind socket\n");
exit(1);
}
// listen and accept
if(listen(sockfd,5)<0)
{
printf("listen error\n");
exit(1);
}
//accept
if((new_sockfd=accept(sockfd,(struct sockaddr *)&pin_addr,(socklen_t *)&pin_addr_size)) < 0)
{
printf("accept error\n");
exit(1);
}
while(1)
{
#if 1
//recv
memset(buf, 0, sizeof(buf));
if(recv(new_sockfd,buf,200,0)==-1)
{
printf("can't receive packet\n");
exit(1);
}
printf("received from client:%s\n",buf);
if(0==strcmp(buf,"quit"))
{
close(new_sockfd);
exit(1);
}
#else
//send
memset(buf, 0, sizeof(buf));
printf("server send:");
scanf("%s",buf);
if(-1==send(new_sockfd,buf,200,0))
{
perror("server send");
exit(1);
}
if(0==strcmp(buf,"quit"))
{
close(new_sockfd);
exit(1);
}
#endif
}
return 0;
}
客户端(client.cpp)代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define myport 319
char buf[200];
int main()
{
//socket
int sockfd;
struct sockaddr_in cin_addr;
int len;
socklen_t conn_len;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(-1== sockfd)
{
perror("creat socket");
exit(1);
}
//connect
cin_addr.sin_family=AF_INET;
cin_addr.sin_addr.s_addr=htonl(INADDR_ANY);
cin_addr.sin_port=htons(myport);
conn_len = sizeof(cin_addr);
if(connect(sockfd,(struct sockaddr*)&cin_addr,conn_len)<0)
{
perror("connect socket");
exit(1);
}
while(1)
{
#if 1
//send
memset(buf, 0, sizeof(buf));
printf("client send:");
scanf("%s",buf);
if(send(sockfd,buf,200,0)==-1)
{
perror("send socket buf");
exit(1);
}
printf("send to server:%s\n",buf);
if(0==strcmp(buf,"quit"))
{
close(sockfd);
exit(1);
}
#else
//recv
memset(buf, 0, sizeof(buf));
if(-1==recv(sockfd,buf,200,0))
{
printf("client recv error\n");
exit(1);
}
printf("recv from server:%s\n",buf);
if(0==strcmp(buf,"quit"))
{
close(sockfd);
exit(1);
}
#endif
}
return 0;
}
编译运行可执行如下图效果:
此致