多进程TCP Server & Client

创建一个TCP Server的连接需要以下几步:

一、服务器端

  • socket:创建服务器监听套接字
  • bind:绑定服务器监听信息到套接字上
  • listen: 开始监听,接收客户端的TCP连接
  • accept:从listen所维护的队列中取出一条已连接的TCP,返回该连接的socket描述字
  • 服务器客户端在连接socket描述字上进行消息通信
  • close:关闭打开着的套接字
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

#define C_DEFAULT_PORT 8000 //默认端口
#define C_BUFFER_SIZE 1024	//缓存buffer大小

void wait_sig(int a)
{
	int t = wait(NULL);
	printf("一个进程%d退出了\n", t);
}

int main()
{
	int port = C_DEFAULT_PORT;
	//信号处理函数
	signal(SIGCHLD, wait_sig);
	//创建Socket
	int C_sock = socket(PF_INET, SOCK_STREAM, 0);
	if (C_sock == -1)
	{
		perror("Socket建立失败");
		return 1;
	}
	else
		printf("Socket建立成功\n");

	//create socket address and initialize
	struct sockaddr_in bind_addr;
	memset(&bind_addr, 0, sizeof(bind_addr));
	bind_addr.sin_family = AF_INET;//地址族协议ipv4
	bind_addr.sin_addr.s_addr = htonl(INADDR_ANY); //设置接受任意地址
	bind_addr.sin_port = htons(port);			   //将host byte order转换为network byte order

	//bind
	int C_bind = bind(C_sock, (struct sockaddr *)&bind_addr, sizeof(bind_addr));
	if (C_bind == -1)
	{
		perror("bind建立失败");
		return 1;
	}
	else
		printf("bind建立成功\n");

	//listen
	int C_listen = listen(C_sock, 5);
	if (C_listen == -1)
	{
		perror("listen建立失败");
		return 1;
	}
	else
		printf("listen建立成功\n");

	while (1)
	{
		int new_sock = accept(C_sock, NULL, NULL);
		if (new_sock == -1)
		{
			perror("new_sock建立失败");
			return 1;
		}
		else
			printf("\nnew_sock建立成功\n");

		int pid = fork();
		if (pid)
		{ //pid不为0,是父进程
			close(new_sock);
		}
		else//子进程
		{				   
			close(C_sock); //子进程中不需要server的sock

			int recv_size;
			char buffer[C_BUFFER_SIZE];
			while (1)
			{
				memset(buffer, 0, C_BUFFER_SIZE);
				int get_size = recv(new_sock, buffer, sizeof(buffer), 0);
				if( get_size == -1)
				{
					perror("recv失败");
					//return 1;
				}
				else 
					printf("客户发来:%s\n", buffer);

				char response[C_BUFFER_SIZE] = "服务器收到了:\0";
				strcat(response,buffer);
				int send_size = send(new_sock, response, strlen(response) + 1, 0);
				if (send_size == -1)
				{
					perror("send失败");
					//return 1;
				}
			}
			close(new_sock); //关闭client的连接
			exit(0);		 //子进程退出
		}
	}
}

二、客户端

  • socket:创建客户端连接套接字
  • connect:向指定服务器发起连接请求
  • 服务器客户端在连接socket描述字上进行消息通信
  • close:关闭打开着的套接字
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <ctype.h>
#include <stdlib.h>

#define C_DEFAULT_PORT 8000 //默认端口
#define C_BUFFER_SIZE 1024	//缓存buffer大小

int main(void)
{
	
	char ipstr[] = "127.0.0.1"; //这是服务器的地址,使用ifconfig来查看
	printf("请输入待连接的IP,输入0使用默认IP: ");
	char T[100];
	scanf("%s",T);
	if(*(int *)T!=0)
		strcpy(ipstr,T);


	//创建Socket
	int C_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (C_sock == -1)
	{
		perror("Socket建立失败");
		return 1;
	}
	else
		printf("Socket建立成功\n");

	//初始化服务器地址
	struct sockaddr_in server_addr;
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET; //地址族协议ipv4
	inet_pton(AF_INET, ipstr, &server_addr.sin_addr.s_addr);
	server_addr.sin_port = htons(C_DEFAULT_PORT);

	//链接服务器
	int C_con = connect(C_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if (C_con == -1)
	{
		perror("connect建立失败");
		return 1;
	}
	else
		printf("connect建立成功\n");

	char buf[C_BUFFER_SIZE];
	while (1)
	{
		// 与服务器通信
		//fgets(buf, sizeof(buf), stdin);
		printf("发送:");
		scanf("%s",buf);
		write(C_sock, buf, strlen(buf));
		int len = read(C_sock, buf, sizeof(buf));
		printf("%s\n",buf);
		//write(STDOUT_FILENO, buf, len);
	}
	
	close(C_sock);//关闭socket
	return 0;
}

posted @ 2022-03-05 16:00  Cheney822  阅读(46)  评论(0编辑  收藏  举报