C语言TCP socket编程

C语言TCP socket编程

TCP 服务器步骤如下:

  • 1.创建等链接套接字fd=socket()
  • 2.绑定待链接套接字bind(fd,地址和端口)
  • 3.监听套接字listen(fd)
  • 4.等待客户端连接connfd=accept(fd) 3次握手
  • 5.与客户端传输数据read(connfd)/write(connfd)
  • 6.与客户端断开连接close(fd)、close(connfd) 4次挥手
    TCP 客户端步骤如下:
  • 1.创建待连接套接字fd=scoket()
  • 2.连接服务器connect(fd) 3次握手
  • 3.与服务器传输数据read(fd)/write(fd)
  • 3.与服务器断开连接close(fd) 4次挥手

TCP服务器

int main(int argc, char const *argv[])
{
	if(argc != 2)
	{
		printf("Usage: %s <PORT>\n", argv[0]);
		exit(0);
	}

	// 创建一个TCP套接字
	int fd = Socket(AF_INET, SOCK_STREAM, 0);

	// 绑定地址(IP:PORT)
	struct sockaddr_in srvaddr, cliaddr;
	bzero(&srvaddr, sizeof(struct sockaddr_in));

	srvaddr.sin_family = AF_INET;
	srvaddr.sin_port = htons(atoi(argv[1]));
	// inet_pton(AF_INET, "192.168.1.166", &srvaddr.sin_addr);
	srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	Bind(fd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr_in));

	// 设置监听套接字 根据你等待连接队列的最大长度
	Listen(fd, BACKLOG);

	// 等待对方的连接请求
	len = sizeof(cliaddr);	
	int connfd = Accept(fd, (struct sockaddr *)&cliaddr, &len); 

	char peeraddr[50];
	bzero(peeraddr, 50);
	printf("new connection: %s:%hu\n",
				inet_ntop(AF_INET, &cliaddr.sin_addr, peeraddr, 50),
				ntohs(cliaddr.sin_port));

	char buf[SIZE];
	while(1)
	{
		bzero(buf, SIZE);
		if(Read(connfd, buf, SIZE) == 0)
			break;

		printf("from Jack: %s", buf);
	}

	close(fd);
	close(connfd);

	return 0;
}

TCP客户端

int main(int argc, char const *argv[])
{
	if(argc != 3)
	{
		printf("Usage: %s <IP> <PORT>\n", argv[0]);
		exit(0);
	}

	// 创建一个TCP套接字
	int fd = Socket(AF_INET, SOCK_STREAM, 0);

	// 准备好对端的地址信息
	struct sockaddr_in srvaddr;
	bzero(&srvaddr, sizeof(srvaddr));

	srvaddr.sin_family = AF_INET;
    //srvaddr.sin_addr.s_addr=inet_addr("192.168.1.166");   
	inet_pton(AF_INET, argv[1], &srvaddr.sin_addr);
	srvaddr.sin_port = htons(atoi(argv[2]));

	// 连接服务端
	Connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));

	char buf[SIZE];
	while(1)
	{
		bzero(buf, SIZE);
		if(fgets(buf, SIZE, stdin) == NULL)
			break;

		Write(fd, buf, strlen(buf));
	}

	close(fd);
	return 0;
}

socket API做了如下封装


ssize_t Write(int fildes, const void *buf, size_t nbyte)
{
	ssize_t retval = write(fildes, buf, nbyte);
	if(retval == -1)
	{
		perror("write() error");
	}

	return retval;
}

ssize_t Read(int fildes, void *buf, size_t nbyte)
{
	int ret = read(fildes, buf, nbyte);
	if(ret == -1)
	{
		perror("read() failed");
	}
	return ret;
}

int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
	int ret = bind(sockfd, addr, addrlen);
	if(ret == -1)
	{
		perror("bind() failed");
	}
	return ret;
}

int Listen(int sockfd, int backlog)
{
	int ret = listen(sockfd, backlog);
	if(ret == -1)
	{
		perror("listen() failed");
	}
	return ret;
}

int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
	int ret = accept(sockfd, addr, addrlen);
	if(ret == -1)
	{
		perror("accept() failed");
	}
	return ret;
}

int Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
	int ret = connect(sockfd, addr, addrlen);
	if(ret == -1)
	{
		perror("connect() failed");
	}
	return ret;
}

int Socket(int domain, int type, int protocol)
{
	int sockfd = socket(domain, type, protocol);
	if(sockfd == -1)
	{
		perror("socket() error");
	}

	return sockfd;
}

int Setsockopt(int sockfd, int level, int optname,
	       const void *optval, socklen_t optlen)
{
	int retval = setsockopt(sockfd, level, optname, optval, optlen);
	if(retval == -1)
	{
		perror("setsockopt() error");
	}

	return retval;
}

int Select(int nfds, fd_set *readfds, fd_set *writefds,
	   fd_set *exceptfds, struct timeval *timeout)
{
	int ret = select(nfds, readfds, writefds, exceptfds, timeout);
	if(ret == -1)
	{
		perror("select() failed");
	}
	return ret;
}

TCP连接流程

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值