Socket编程--简单回射服务器的实现

TCP三次握手

回射客户/服务器

这里写图片描述

Socket函数

1.包含头文件<sys/socket.h>

2.功能:创建一个套接字用于通信

3.原型

        int socket(int domain,int type,int protocol);

4.参数

    domain:指定通信协议族

   type:指定socket类型,流式套接字SOCK_STREAM(TCP),数据报套接字SOCK_DGRAM(UDP),原始套接字SOCK_RAM

    protocol:协议类型

 5.返回值:成功返回非负整数,它与文件描述符类似,我们把它称为套接字描述字,简称套接字。失败返回-1.

bind函数

    1.包含头文件<sys/socket.h>

    2.绑定一个本地地址到套接字

    3.原型:    

            int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);

    4.参数

            sockfd:socket函数返回的套接字

            addr:要绑定的地址

            addrlen:地址长度

    5.返回值:    

            成功返回0,失败返回-1

listen函数

    1.包含头文件<sys/socket.h>

    2.功能:将套接字用于监听进入的连接

    3.原型:

        int listen(int sockfd,int backlog);

    4.参数

        sockfd:socket函数返回的套接字

        backlog:规定内核为此套接字排队的最大连接个数

    5.返回值:

        成功返回0,失败返回-1

    一般来说,listen函数应该在调用socket函数和bind函数之后,调用函数accept之前。

    对于给定的监听套接口,内核要维护两个队列:

        1.已由客户发出并到达服务器,服务器正在等待完成相应的TCP三路握手过程

        2.已完成连接的队列

accept函数

    1.包含头文件<sys/socket.h>

    2.功能:从已完成连接队列返回第一个连接,如果已经完成连接队列为空,则阻塞。

    3.原型    int accept(int socked,struct sockaddr *addr,socklen_t *addrlen);

    4.参数

        sockfd:服务器套接字

        addr:将返回对等方的套接字地址

        addrlen:返回对等方的套接字地址长度

   5.返回值:成功非负整数,失败返回-1;

服务器端:

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

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#define ERR_EXIT(m)			\
	do				\
	{				\
		perror(m);		\
		exit(EXIT_FAILURE);	\
	}while(0);			\

int main(void)
{
	int listenfd;
	
	if((listenfd =  socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
	{
		ERR_EXIT("socket");	
	}

	/*if(listenfd = socket(PF_INET,SOCK_STREAM,0)<0)*/

	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));	//初始化

	servaddr.sin_family = AF_INET;		//地址族	
	servaddr.sin_port = htons(5188);	//端口号
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	/*seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");*/
	/*iner_aton("127.0.0.1",&servaddr.sin_addr);*/

	/*设置地址重复利用*/
	int on = 1;
	if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0)
	{
		ERR_EXIT("setsockopt");
	}

	/*绑定*/
	if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0 )
	{
		ERR_EXIT("bind");
	}
	
	/*绑定监听*/
	if(listen(listenfd,SOMAXCONN) < 0)
	{
		ERR_EXIT("listen");
	}        


	struct sockaddr_in peeraddr;		/*目标地址*/
	socklen_t peerlen = sizeof(peeraddr);	

	int conn;				/*已连接套接字*/

	/*等待连接*/

	if( (conn = accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen)) < 0 )
	{
		ERR_EXIT("accept");
	}

	else 
	{	
		printf("ip = %s,port = %d\n",inet_ntoa(peeraddr.sin_addr),peeraddr.sin_port);
		char recvbuf[1024];

	 	while(1)
		{
			memset(recvbuf,0,sizeof(recvbuf));
	 		int ret = read(conn,recvbuf,sizeof(recvbuf));
			fputs(recvbuf,stdout);
			write(conn,recvbuf,ret);
		}
	}
		
	close(conn);
	close(listenfd);

	return 0;
                                                                                                                                                                                                   
}

客户端:

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

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#define ERR_EXIT(m)			\
	do				\
	{				\
		perror(m);		\
		exit(EXIT_FAILURE);	\
	}while(0);			\

int main(void)
{
	int sock;
	char sendbuf[1024] = {0};
	char recvbuf[1024] = {0};

	if((sock =  socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
	{
		ERR_EXIT("socket");	
	}

	/*if(listenfd = socket(PF_INET,SOCK_STREAM,0)<0)*/

	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));	//初始化

	servaddr.sin_family = AF_INET;		//地址族	
	servaddr.sin_port = htons(5188);	//端口号
	/*servaddr.sin_addr.s_addr = htonl(INADDR_ANY);*/
	servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	/*iner_aton("127.0.0.1",&servaddr.sin_addr);*/

	if( connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
	{
		ERR_EXIT("connect");
	}

	else 
	{	
		printf("ip = %s,port = %d\n",inet_ntoa(servaddr.sin_addr),servaddr.sin_port);
		while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL)
		{
			write(sock,sendbuf,strlen(sendbuf));
			read(sock,recvbuf,sizeof(recvbuf));

			fputs(recvbuf,stdout);

			memset(sendbuf,0,sizeof(sendbuf));
			memset(recvbuf,0,sizeof(recvbuf));
		}
	
	}
	close(sock);

	return 0;
                                                                                                                                                                                                   
}



测试效果:




猜你喜欢

转载自blog.csdn.net/qq_34938530/article/details/79611148