Cetus Group
Cetus Logo
Информационные системы и программное обеспечение



Файлы проекта

Поддержка

 
Межмашинное взаимодействие в C/C++
Редакция 20.07.2006 : Изменения 30:09:2006
А.Г. © Часть 1 - "Сокеты в C"

Сокеты позволяют реализовать взаимодействие процессов, как это было описано в примере работы с сокетами в Python. В представленном ниже примере работы с сокетами на C сервер выполняет преобразование отправленной клиентом строки в нижнем регистре к верхнему регистру.и возвращает результат клиенту. Для упрощения примера передается строка фиксированного размера. При этом необходимо принять во внимание, что несоответствие размера переданной строки может привести к сбою в работе функции printf.

Программа-сервер:
-- Создает сокет и устанавливает для него порт 8888 (выбран как один из свободных).
-- Устанавливает обработчик catcher для корректного закрытия соединения.
-- Выполняет цикл опроса подключений клиентов с созданием нового процесса для обслуживания соединения.
-- Преобразует полученные данные к верхнему регистру и возвращает результат клиенту.
(Создание нового процесса не является необходимым условием работы с несколькими соединениями.)

#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>

#define SIZE sizeof(struct sockaddr_in)
#define BS 20

void catcher(int sig);
int newsockfd;

int main() {
	int sockfd;
	char c[BS];
	struct sockaddr_in server = {AF_INET, 8888, INADDR_ANY};
	static struct sigaction act;
	
	act.sa_handler = catcher;
	sigfillset(&act.sa_mask);
	sigaction(SIGPIPE, &act, NULL);
	
	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)	{
		perror("unable to create socket");
		exit(1);
	}
	
	if(bind(sockfd, (struct sockaddr *)&server, SIZE) == -1) {
		perror("unsuccessful bind");
		exit(1);
	}
	
	if(listen(sockfd, 5) == -1) {
		perror("unsuccessful listen");
		exit(1);
	}
	
	for(;;) {
		if((newsockfd = accept(sockfd, NULL, NULL)) == -1) {
			perror("could not accept");
			continue;
		}
		printf("connect\n");
		if(fork() == 0) {
			int i;
			while(recv(newsockfd, c, BS, 0) > 0) {
				for(i=0;i<BS;i++)
					c[i] = toupper(c[i]);
				send(newsockfd, c, BS, 0);
			}
			close(newsockfd);
			exit(0);
		}
		close(newsockfd);	
	}
}

void catcher(int sig) {
	close(newsockfd);
	exit(0);
}

Программа-клиент:
-- Создает сокет и присоединяется к порту 8888 указанного хоста (в данном случае - локального).
-- Отправляет и читает строку.
-- Закрывает соединение и выводит результат на стандартный вывод.

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define SIZE sizeof(struct sockaddr_in)
#define BS 20

int main() {
	int sockfd;
	char c[BS+1]="hello, world!!!    ", rc[BS+1];
	struct sockaddr_in server = {AF_INET, 8888};
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd  == -1)	{
		perror("unable to create socket");
		exit(1);
	}
	if(connect(sockfd,(struct sockaddr *)&server,SIZE) == -1) {
		perror("unable to connect");
		exit(1);
	}
	printf("client snd: %s\n",c);	
	send(sockfd, c, BS, 0);
	printf("server rsp: ");
	if(recv(sockfd, rc, BS, 0)>0)
		printf("%s\n", rc);
	else {
		printf("communications ended\n");
		close(sockfd);
		exit(1);
	}
}

Компиляция программ в ОС Linux может быть выполнена следующим образом:

gcc server.c -o server
gcc client.c -o client

Необходимо отметить, что в приведенном примере выполняется такая же последовательность операций по созданию сокета, как и в Python-примере. Больший объем кода определяется более тщательной реализацией обработки ошибок.

При выполнении программ примера первым должен быть запущен сервер (удобно в отдельном терминале). Выполняем, проверяем результаты. На этом все.


Copyright©2005, Cetus Group : All rights reserved.