Linux 에서 Socket 기반 다 중 프로 세 스 실시 간 통신 실현
8699 단어 linuxsocket커 뮤 니 케 이 션프로 세 스실시 간
본 고 는 Socket 을 바탕 으로 하 는 다 중 프로 세 스 간 통신 의 실현 방법 을 제시 했다.원 리 는 통신 서버 (server) 로 각 프로 세 스 간 의 통신 을 전환 하 는 프로 세 스 를 만 드 는 것 이다.연결 요 구 를 감시 하 는 listening Socket 을 먼저 시작 하고 설명 (Descriptor) 번 호 를 미리 정 의 된 fd 에 추가 합 니 다.set 의 집합 중, 이 fdset 의 집합 은 listening Socket 과 나중에 생 성 된 통신 Socket 의 설명 번 호 를 저장 하 는 데 사 용 됩 니 다.서버 는 시스템 콜 select 를 사용 하여 이 집합 에 있 는 모든 socket 에 데이터 가 도 착 했 는 지 실시 간 으로 확인 합 니 다. 데이터 가 listening Socket 에 도착 하면 클 라 이언 트 가 시작 한 연결 요청 이 분명 합 니 다. 그래서 새로운 통신 Socket 을 생 성하 여 이 클 라 이언 트 와 연결 하고 생 성 된 Socket 설명 번 호 를 fd 에 추가 합 니 다.set 의 집합 에서 클 라 이언 트 의 ID 번호 와 이에 대응 하 는 Socket 의 설명 번 호 를 ID 등록 표 에 기록 합 니 다.만약 에 데이터 가 특정한 통신 Socket 에 도착 하면 이것 은 특정한 클 라 이언 트 가 제기 한 통신 요청 일 것 입 니 다. 데 이 터 를 읽 고 수신 클 라 이언 트 ID 번 호 를 꺼 내 고 ID 등록 표 에서 이에 대응 하 는 Socket 설명 번 호 를 찾 아 데 이 터 를 해당 하 는 Socket 을 통 해 수신 클 라 이언 트 로 전송 합 니 다.
다른 프로 세 스 는 클 라 이언 트 (client) 로 사 용 됩 니 다.클 라 이언 트 의 동작 은 먼저 통신 소켓 연결 서버 단 을 만 든 다음 통신 소켓 을 통 해 편 지 를 보 내 고 받 는 것 이다.
구체 적 인 절차 실현 과 설명 을 드 리 겠 습 니 다.
먼저 서버 엔 드 의 프로그램 을 보 여 줍 니 다. 여기 서 두 개의 클 라 이언 트 가 실시 간 으로 통신 할 것 이 라 고 가정 합 니 다. 클 라 이언 트 A 는 클 라 이언 트 B 에 문자 1 을 보 내 고 클 라 이언 트 B 는 클 라 이언 트 A 에 문자 2 를 보 냅 니 다.
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
int main()
{
int rcd ;
struct sockaddr_un server_sockaddr ;
int backlog ;
ushort ci ;
int watch_fd_list[3] ;
fd_set catch_fd_set ;
fd_set watchset ;
int new_cli_fd ;
int maxfd;
int socklen ,server_len;
struct sockaddr_un cli_sockaddr ;
struct {
char module_id ; /* Module ID */
int cli_sock_fd ; /* Socket ID */
} cli_info_t[2] ;
for (ci=0;ci<=1;ci++)
cli_info_t[ci].cli_sock_fd=-1;
for (ci=0;ci<=2;ci++)
watch_fd_list[ci]=-1;
int server_sockfd,client_sockfd;
server_sockfd = socket( AF_UNIX, SOCK_STREAM, 0 ) ;
server_sockaddr.sun_family = AF_UNIX ;
strcpy( server_sockaddr.sun_path, "server_socket" ) ;
server_len=sizeof(server_sockaddr);
rcd = bind( server_sockfd, ( struct sockaddr * )&server_sockaddr, server_len ) ;
backlog = 5 ;
rcd = listen( server_sockfd, backlog ) ;
printf("SERVER::Server is waitting on socket=%d
",server_sockfd);
watch_fd_list[0]=server_sockfd;
FD_ZERO( &watchset ) ;
FD_SET( server_sockfd, &watchset ) ;
maxfd=watch_fd_list[0];
위의 프로그램 에서 서버 는 listening Socket (server sockfd) 을 생 성하 고 Socket 감시 집합 (watchset) 을 초기 화하 고 listening Socket 을 Socket 감시 집합 에 넣 습 니 다.
while (1){
char ch;
int fd;
int nread;
catch_fd_set=watchset;
rcd = select( maxfd+1, &catch_fd_set, NULL, NULL, (struct timeval *)0 ) ;
위의 프로그램 에서 서버 는 시스템 호출 함수 select 를 사용 하여 Socket 감시 집합 에 데이터 가 있 는 지 실시 간 으로 확인 합 니 다.
if ( rcd < 0 ) {
printf("SERVER::Server 5
");
exit(1);
}
if ( FD_ISSET( server_sockfd, &catch_fd_set ) ) {
socklen = sizeof( cli_sockaddr ) ;
new_cli_fd = accept( server_sockfd, ( struct sockaddr * )
&( cli_sockaddr ), &socklen ) ;
printf(" SERVER::open communication with Client %s on socket %d
",
cli_sockaddr.sun_path,new_cli_fd);
for (ci=1;ci<=2;ci++){
if(watch_fd_list[ci] != -1) continue;
else{
watch_fd_list[ci] = new_cli_fd;
break;
}
}
FD_SET(new_cli_fd , &watchset ) ;
if ( maxfd < new_cli_fd ) {
maxfd = new_cli_fd ;
}
for ( ci=0;ci<=1;ci++){
if(cli_info_t[ci].cli_sock_fd == -1) {
cli_info_t[ci].module_id=cli_sockaddr.sun_path[0];
cli_info_t[ci].cli_sock_fd=new_cli_fd;
break;
}
}
continue;
}
위의 프로그램 에서 서버 는 시스템 호출 함수 FD 를 사용 합 니 다.ISSET 는 클 라 이언 트 의 연결 요청 이 Listening Socket 에 도 착 했 는 지 확인 합 니 다. 반환 값 이 0 이상 이면 서버 는 새로운 통신 Socket (new cli fd) 을 생 성하 여 클 라 이언 트 와 연결 합 니 다.새로 생 성 된 통신 소켓 을 소켓 감시 집합 (FD SET) 에 넣 습 니 다.클 라 이언 트 의 정보 (ID 번호 와 Socket 설명 번호) 를 레 지 스 트 cli 에 저장 합 니 다.info_t 중
for ( ci = 1; ci<=2 ; ci++ ) {
int dst_fd = -1 ;
char dst_module_id;
char src_module_id;
int i;
if (watch_fd_list[ ci ]==-1) continue;
if ( !FD_ISSET( watch_fd_list[ ci ], &catch_fd_set ) ) {
continue ;
}
ioctl(watch_fd_list[ ci ],FIONREAD,&nread);
if (nread==0){
continue;
}
read( watch_fd_list[ ci ], &dst_module_id, 1 ) ;
for (i=0;i<=1;i++){
if(cli_info_t[i].module_id == dst_module_id)
dst_fd= cli_info_t[i].cli_sock_fd;
if(cli_info_t[i].cli_sock_fd==watch_fd_list[ ci ])
src_module_id= cli_info_t[i].module_id;
}
read( watch_fd_list[ ci ], &ch, 1 ) ;
printf("SERVER::char=%c to Client %c on socket%d
",ch, dst_module_id,dst_fd);
write(dst_fd,&src_module_id, 1 ) ;
write(dst_fd,&ch, 1 ) ;
}
}
}
위의 프로그램 에서 어떤 통신 Socket 에 데이터 가 도착 하면 Server 는 데 이 터 를 읽 고 수신 클 라 이언 트 ID 번 호 를 꺼 냅 니 다.ID 등록 표 에서 수신 클 라 이언 트 에 대응 하 는 Socket 설명 번 호 를 찾 습 니 다.그리고 데 이 터 를 대응 하 는 Socket 을 통 해 수신 클 라 이언 트 로 전송 합 니 다.
클 라 이언 트 클 라 이언 트 A 를 위 한 프로그램
Client B 프로그램 은 char dstmodule_id='B'; char dst 로 변경module_id='A'; char ch='1'; char char ch = '2' 로 변경 하기;기왕에.
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(){
int client_sockfd;
int len;
struct sockaddr_un server_sockaddr,cli_sockaddr;
int result;
char dst_module_id='B';
char ch='1';
char src_module_id;
client_sockfd= socket(AF_UNIX,SOCK_STREAM,0);
cli_sockaddr.sun_family = AF_UNIX ;
strcpy( cli_sockaddr.sun_path, "A" ) ;
bind(client_sockfd,(struct sockaddr * )&cli_sockaddr, sizeof( cli_sockaddr ) ) ;
server_sockaddr.sun_family=AF_UNIX;
strcpy( server_sockaddr.sun_path, "server_socket" ) ;
len=sizeof(server_sockaddr);
result = connect(client_sockfd,( struct sockaddr * )&server_sockaddr,len);
if (result <0){
printf("ClientA::error on connecting
");
exit(1);
}
printf("ClientA::succeed in connecting with server
");
sleep(10);
write(client_sockfd,&dst_module_id,1);
write(client_sockfd,&ch,1);
read (client_sockfd,&src_module_id,1);
read (client_sockfd,&ch,1);
printf("ClientA::char from Client %c =%c
", src_module_id,ch);
close (client_sockfd);
}
다음은 샘플 프로그램의 실행 결과 입 니 다.
[root@zhou test]# ./server &
[3] 4301
[root@zhou test]# SERVER::Server is waitting on socket=3
./clientA & ./clientB &
[4] 4302
[5] 4303
ClientA::succeed in connecting with server
SERVER::open communication with Client A on socket 4
[root@zhou test]# SERVER::open communication with Client B on socket 5
ClientB::succeed in connecting with server
SERVER::char=1 to Client B on socket5
ClientB::char from Client A =1
SERVER::char=2 to Client A on socket4
ClientA::char from Client B =2
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
용감한 바로 가기 및 우분투 응용 프로그램안녕하세요 여러분, 이 기사에서는 모든 사이트에서 pwa를 생성하고 실행기 응용 프로그램으로 추가하는 방법을 설명하고 싶습니다. 일부 웹사이트는 PWA로 설치를 허용하지 않지만 유사한 애플리케이션을 원합니다. 1. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.