欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux/macOS 服务端/客户端简单通信

程序员文章站 2022-03-04 08:46:14
...

嗯......,感觉还是CSDN界面友好点,博客园一股Windows风。

好久之前总结的简单Linux 服务器和客户端的通信代码现在搬过来。

client.cpp

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

#define MSG_LEN 1024
#define PORT 8886
#define IP "127.0.0.1"

int main(int argc,char* argv[]){
	int socket_fd,ret = -1;
	char send_buf[MSG_LEN] = {0,};
	char recv_buf[MSG_LEN] = {0,};
	struct sockaddr_in serverAddr;
	
	socket_fd = socket(AF_INET,SOCK_STREAM,0);
	if(socket_fd < 0){
		std::cout << "Failed to create socket" << std::endl;
		exit(-1);
	}

	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = PORT;
	serverAddr.sin_addr.s_addr = inet_addr(IP);
	
	ret = connect(socket_fd,(struct sockaddr*) &serverAddr,sizeof(struct sockaddr));
	
	if(ret < 0){
		std::cout << "Failed to connect server" << std::endl;
		exit(-1);
	}

	while(1){
		memset(send_buf,0,MSG_LEN);
		std::cin >> send_buf;

		send_buf[MSG_LEN-1] = '\0';
		ret = send(socket_fd,send_buf,strlen(send_buf),0);
		if(ret < 0){
			std::cout << "Failed to send data" << std::endl;
			continue;
		}
		
		ret = recv(socket_fd,recv_buf,MSG_LEN,0);
		recv_buf[ret] = '\0';
		std::cout << "recv: " << recv_buf << std::endl;
		
	}
	close(socket_fd);
	return 0;
}

Server.cpp

#include <iostream>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 8886
#define MSG_LEN 1024
int main(int argc,char* argv[]){
	int socket_fd,accept_fd,ret = -1;
	int on = 1;
	int backlog = 10;
	char recv_buf[MSG_LEN] = {0,};
	
	struct sockaddr_in localAddr,remoteAddr;

	socket_fd = socket(AF_INET,SOCK_STREAM,0);
	if(socket_fd == -1){
		std::cout << "Failed to create socket!" << std::endl;
	}	
	// set socket options
 	ret = setsockopt(socket_fd,
						SOL_SOCKET,
						SO_REUSEADDR,
						&on,
						sizeof(on));
	if(ret == -1){
		std::cout << "Failed to set socket options" << std::endl;
	}
	localAddr.sin_family = AF_INET;
	localAddr.sin_port = PORT;
	localAddr.sin_addr.s_addr = INADDR_ANY;
	bzero(&(localAddr.sin_zero),8);
	
	// bind
 	ret = bind(socket_fd,(struct sockaddr*) &localAddr,sizeof(struct sockaddr));

	if(ret == -1){
		std::cout << "Failed to bind addr" << std::endl;
		exit(-1);
	}

	// listen
	ret = listen(socket_fd,backlog);
	if(ret == -1){
		std::cout << "Failed to listen socket" << std::endl;
		exit(-1);
	}

	// recv data
	while(1){
		socklen_t addr_len = sizeof(struct sockaddr);
		accept_fd = accept(socket_fd,(struct sockaddr*) &remoteAddr, &addr_len);
		while(1){
			ret = recv(accept_fd,(void *)recv_buf,MSG_LEN,0);
			if(ret == 0){
				break;
			}
		
			std::cout << "recv: " << recv_buf << std::endl;
			// response data
			send(accept_fd,(void *)recv_buf,MSG_LEN,0);
			memset(recv_buf,0,MSG_LEN);
		}
	}
	
	close(socket_fd);
	return 0;
}

这是最简单粗暴的服务端/客户端通信的例子了,如果开启一个server,开启多个客户端连接发送数据,server只能与最先连接的客户端交互。此程序可以使用fork和多线程解决该问题。