Linux系统下实现Socket通信,TCP协议三次握手

首先,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;
	
}

编译运行可执行如下图效果:

                                                                                                                                                    此致

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值