03.5 基于socket的服务端客户端通信

代码如下:

服务端

#include <sys/socket.h>//sever
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <strings.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/tcp.h>

char host_name[20];
int port = 7777;

int main()
{
	struct sockaddr_in sin, pin;
	int sock_descriptor, temp_sock, address_size;
	int i, recvlen, on = 1;
	int nZero = 1;
	int leftlen = 0, sendlen = 0, retlen = 0;
	char buf[16384], sendbuf[1024] = {0}, *ptr = NULL;

	//通过socket(int domain,int type,int protocol)的函数原型创建AF_INIT协议族的流
	//类型的socket,当然type除了流socket的之外还有SOCKET_RAW,
	//据说这种类型的socket甚至可以伪装数据包
	sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
	setsockopt(sock_descriptor, SOL_SOCKET, SO_REUSEADDR, &nZero, sizeof(int));
	setsockopt(sock_descriptor, SOL_SOCKET, SO_REUSEPORT, &nZero, sizeof(int));
	setsockopt(sock_descriptor, IPPROTO_TCP, TCP_NODELAY, (char*)&nZero, sizeof(int));
	//int keepAlive = 1;
	//setsockopt(sock_descriptor, SOL_SOCKET, SO_KEEPALIVE,(void *)keepAlive, sizeof(keepAlive));

	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = INADDR_ANY;
	//地址结构的端口地址,port是主机字节序,通过htons()进行字节序转换成网络字节序
	sin.sin_port = htons(port);
	//将sin的地址和socket文件描述符绑定到一起,绑定是数据接收和发//送的前提
	if (bind(sock_descriptor, (struct sockaddr *)&sin, sizeof(sin)) == -1)
	{
		perror("call to bind");
		exit(1);
	}
	//监听用来初始化服务器可连接队列,因为一次只能处理一个连接请求
	//当收到多个请求,将会存储在队列中,先到先得
	if (listen(sock_descriptor, 100) == -1)
	{
		perror("call to listen");
		exit(1);
	}
	printf("Accpting connections...\n");

	address_size = sizeof(pin);


	//接收客户机,返回句柄
	temp_sock = accept(sock_descriptor, (struct sockaddr *)&pin, &address_size);
	while (1)
	{
		//temp_sock = accept(sock_descriptor,(struct sockaddr *)&pin,&address_size);
		char buffer[1024] = { 0 };
		//句柄分辨不同客户端
		printf("temp_sock=%d\n",temp_sock);
		//链接失败
		if (temp_sock == -1)
		{
			perror("call to accept");
			exit(1);
		}
		//int recvlen = recv(temp_sock, buf,sizeof(buf),0);
		
		ptr = buffer;
		//收数据传入buffer
		int recvlen = recv(temp_sock, ptr, 1024, 0);
		//断开连接
		if (recvlen == -1)
		{
			perror("call to recv");
			exit(1);
		}
		else if (recvlen == 0)//无数据
		{
			printf("断线重连...\n");
			temp_sock = accept(sock_descriptor, (struct sockaddr *)&pin, &address_size);
			continue;
		}
		//send(tmp_sock, buffer, 1024, 0);
		//收到数据,打印
		printf("received msg: %s, size:%d\n", buffer, recvlen);
		//break;
	
		//send data
		retlen = 0;
		ptr = sendbuf;
		//	printf("sendlen1 = %d\n", sendlen);
		//while (leftlen) {
		//	printf("sendbuf1:%s\n", sendbuf);
			printf("sever_input:");
		//	gets(sendbuf);
			scanf("%s", &sendbuf);
		//	sprintf(sendbuf, "hello\n");
		//	printf("sendbuf2:%s\n", sendbuf);
		//	printf("sendlen2 = %d\n", sendlen);
			sendlen = strlen(sendbuf);
		//	printf("sendlen3 = %d\n", sendlen);
			//表示已经完成一次发送
			if (0 == leftlen) {
				leftlen = sendlen;
				printf("leftlen = sendlen;\n");
			}
			//退出标识符
			if (0 == strcmp(sendbuf, "quit")) {
				printf("quit...\n");
				break;
			}
			//发送
			printf("retlen1 = %d\n", retlen);
			//retlen = send(sock_descriptor, sendbuf, sendlen, 0);
			retlen = send(temp_sock, sendbuf, sendlen, 0);
			printf("retlen2 = %d\n", retlen);
			if (retlen < 0) {
				printf("retlen < 0\n");
				if (errno == EINTR)
					retlen = 0;
				else{
					printf("exit...");
					exit(1);
				}
			}
			else{
				printf("retlen3 = %d\n", retlen);
			}
			leftlen -= retlen;
		//}

	}

	close(temp_sock);
	close(sock_descriptor);
	return 0;
}

客户端

#include <stdio.h>  
#include <string.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <syslog.h>  
#include <errno.h>  
#include <stdlib.h>  
#define MAX_LISTEN_NUM 5  
#define SEND_BUF_SIZE 100  
#define RECV_BUF_SIZE 100  
#define SERVER_PORT 7777 
char *	server_ip = "192.168.60.253";
int main()
{
	int sock_fd = 0;
	char recvbuf[RECV_BUF_SIZE] = { 0 };
	char sendbuf[SEND_BUF_SIZE] = { 0 };
	int recvlen = 0;
	int retlen = 0;
	int sendlen = 0;
	int leftlen = 0;
	char *ptr = NULL;  //指向缓冲区的指针 
	struct sockaddr_in ser_addr;

	//memset(&ser_addr, 0, sizeof(ser_addr));  
	bzero(&ser_addr, sizeof(ser_addr));
	ser_addr.sin_family = AF_INET;  //地址族inet
									//inet_aton("192.168.60.253", (struct in_addr *)&ser_addr.sin_addr);  
	inet_pton(AF_INET, server_ip, &ser_addr.sin_addr);
	//将整型变量从主机字节顺序转变成网络字节顺序
	ser_addr.sin_port = htons(SERVER_PORT);
	sock_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (sock_fd < 0)
	{
		perror("connecting to socket\n");
		fprintf(stderr, "%s:%d, create socket failed", __FILE__, __LINE__);
		exit(1);
	}

	int nZero = 1;//套接口初始化 
	setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &nZero, sizeof(int));
	setsockopt(sock_fd, SOL_SOCKET, SO_REUSEPORT, &nZero, sizeof(int));
	//if(connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr)) < 0)  
	if (connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr)) == -1)
	{
		fprintf(stderr, "%s:%d, connect socket failed", __FILE__, __LINE__);
		exit(1);
	}
	//	sprintf(sendbuf, "hello server\n");  

	//send data  
	//sendlen = strlen(sendbuf) +1;  
	retlen = 0;
	//leftlen = sendlen;  
	ptr = sendbuf;

	//while(leftlen){  //发送缓存数据   
	while (1) {  //发送缓存数据   
		printf("input message:");
		gets(sendbuf); //
					   //scanf("%s",sendbuf);
		sendlen = strlen(sendbuf);

		//说明一条消息已经发送完毕
		if (0 == leftlen)
		{
			leftlen = sendlen;
		}

		//退出条件
		if (0 == strcmp(sendbuf, "quit"))
		{
			printf("quit...\n");
			break;
		}

		//printf("retlen:%d,sock_fd:%d,sendlen:%d,leftlen:%d\n", retlen, sock_fd, sendlen, leftlen);
		//retlen = send(sock_fd, ptr, sendlen, 0);  
		//		printf("sendbuf:%s\n",sendbuf);
		retlen = send(sock_fd, sendbuf, sendlen, 0);
		//printf("retlen:%d,sock_fd:%d,sendlen:%d,leftlen:%d\n", retlen, sock_fd, sendlen, leftlen);
		if (retlen < 0)
		{
			printf("retlen < 0\n");
			if (errno == EINTR)  //判断信号是否中断 
				retlen = 0;
			else
				printf("exit...");
			exit(1);
		}
		leftlen -= retlen;
		//		printf("leftlen=%d\n",leftlen);
		//ptr += retlen;
		//		printf("retlen:%d,sock_fd:%d,sendlen:%d,leftlen:%d\n",retlen,sock_fd,sendlen,leftlen);

		//receive data  
		recvlen = 0;  //重置
		retlen = 0;
		ptr = recvbuf;  //指针ptr->缓冲区函数
		leftlen = RECV_BUF_SIZE - 1;
		//do {
			retlen = recv(sock_fd, ptr, leftlen, 0);
			if (retlen < 0)
			{
				if (errno == EINTR)
					retlen = 0;
				else
					exit(1);
			}
			recvlen += retlen;
			leftlen -= retlen;
			ptr += retlen;
		//} while (recvlen && leftlen);
		printf("receive data is : %s", recvbuf);
		//     sprintf(sendbuf, "hello server/n"); 	
	}  //while(1)

	close(sock_fd);

}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值