'Linux API/network'에 해당되는 글 37건

  1. 2023.07.21 bind(): Address already in use
  2. 2023.06.23 recv 와 read 차이
  3. 2022.06.09 AF_PACKET로 link layer 열기
  4. 2022.05.11 linux tcp server listen accept connect
  5. 2022.03.25 ssl socket 예제
  6. 2020.09.29 TCP timeout
  7. 2020.09.01 UDS (Unix Domain Socket)
  8. 2019.07.03 raw socker과 promiscous mode
  9. 2019.05.24 리눅스 UDP 소켓
  10. 2019.05.24 리눅스 TCP 소켓
Linux API/network2023. 7. 21. 18:56

libmodbus 사용하면 희한하게 일정 시간 이후에나 해당 소켓이 사용가능하도록 풀리는데

libmodbus가 종료시 제대로 bind를 풀어주지 않아 발생하는 것으로 예측만 했는데, 일단은~ 회피법을 찾은 듯.

 

SO_REUSEADDR

[링크 : https://www.inflearn.com/questions/20648/%EC%97%90%EB%9F%AC-bind-address-already-in-use]

 

딱 내가 겪고 있던 증상

이는 기존 프로그램이 종료되었지만, 비정상종료된 상태로 아직 커널이 bind정보를 유지하고 있음으로 발생하는 문제다. 보통 1-2분 정도 지나만 커널이 알아서 정리를 하긴 하지만, 그 시간동안 기달려야 한다는 것은 상당히 번거로운 일이다. 이 경우 다음과 같은 코드를 삽입함으로써 문제를 해결할 수 있다.

int sock = socket(...);
setsockopt(sockSOL_SOCKETSO_REUSEADDR, (char *)&bf, (int)sizeof(bf));

이렇게 하면 커널은 기존에 bind로 할당된 소켓자원을 프로세스가 재 사용할 수 있도록 허락한다.

[링크 : https://www.joinc.co.kr/w/Site/Network_Programing/AdvancedComm/SocketOption]

 

+

2023.08.01

int      option;

server_socket = socket( PF_INET, SOCK_STREAM, 0);

option = 1;          // SO_REUSEADDR 의 옵션 값을 TRUE 로
setsockopt( server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option) );

[링크 : https://m.blog.naver.com/cache798/130080237440]

 

프로토 타입은 아래와 같은데 SO_REUSEADDR 은 optname으로 level이 SOL_SOCKET 이라..

optval에는 또 어떻게 넣어줘야 하려나

       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
       int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

[링크 : https://linux.die.net/man/2/setsockopt]

'Linux API > network' 카테고리의 다른 글

recv 와 read 차이  (0) 2023.06.23
AF_PACKET로 link layer 열기  (0) 2022.06.09
linux tcp server listen accept connect  (0) 2022.05.11
ssl socket 예제  (0) 2022.03.25
TCP timeout  (0) 2020.09.29
Posted by 구차니
Linux API/network2023. 6. 23. 15:40

flag 안쓰면(NULL) 둘 다 거의 동일하다 라고 보면 될 듯.

       The  only  difference  between  recv()  and  read(2) is the presence of
       flags.  With a zero flags argument, recv() is generally  equivalent  to
       read(2) (but see NOTES).  Also, the following call

           recv(sockfd, buf, len, flags);

       is equivalent to

           recvfrom(sockfd, buf, len, flags, NULL, NULL);

NOTES
       If  a  zero-length datagram is pending, read(2) and recv() with a flags
       argument of zero provide different  behavior.   In  this  circumstance,
       read(2) has no effect (the datagram remains pending), while recv() con‐
       sumes the pending datagram.

       The socklen_t type was invented by POSIX.  See also accept(2).

       According to POSIX.1, the msg_controllen field of the msghdr  structure
       should  be typed as socklen_t, and the msg_iovlen field should be typed
       as int, but glibc currently types both as size_t.

       See recvmmsg(2) for information about a Linux-specific system call that
       can be used to receive multiple datagrams in a single call.

[링크 : https://linux.die.net/man/2/recv]

 

[링크 : https://github.com/get-Pork-Belly/Webserv/issues/18]

'Linux API > network' 카테고리의 다른 글

bind(): Address already in use  (0) 2023.07.21
AF_PACKET로 link layer 열기  (0) 2022.06.09
linux tcp server listen accept connect  (0) 2022.05.11
ssl socket 예제  (0) 2022.03.25
TCP timeout  (0) 2020.09.29
Posted by 구차니
Linux API/network2022. 6. 9. 11:17

etherCAT 이라는 사악한(?) 프로토콜 때문에 해당 장비 개발자에게 주워들은 이야기

 

AF_PACKET 이라는걸로 열면 link layer로 열려서 통신이 가능해서

etherCAT 이라고 특별한 드라이버를 설치하는건 아니라고 한다.

 

AF_INET 를 주로 사용했지 다른걸 찾아볼 생각을 안했구나..

Name Purpose Man page
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK Appletalk ddp(7)
AF_PACKET Low level packet interface packet(7)

[링크 : https://linux.die.net/man/2/socket]

[링크 : https://iplab.naist.jp/class/2018/materials/hands-on/layer-2-raw-socket/]

'Linux API > network' 카테고리의 다른 글

bind(): Address already in use  (0) 2023.07.21
recv 와 read 차이  (0) 2023.06.23
linux tcp server listen accept connect  (0) 2022.05.11
ssl socket 예제  (0) 2022.03.25
TCP timeout  (0) 2020.09.29
Posted by 구차니
Linux API/network2022. 5. 11. 15:20

서버 사이드 listen + accept

클라이언트 사이드 connect

[링크 : https://charsyam.wordpress.com/2018/01/09/입-개발-ipv4-tcp-socket-listen-에서-accept-까지/]

 

[링크 : https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select]

[링크 : https://velog.io/@jyongk/TCP-Socket-Blocking-Non-Blocking]

[링크 : https://ospace.tistory.com/189]

 

accept poll 처리

accept 시에 돌려받는 fd로 io를 처리하면 accept 역시 poll로 처리가 가능해진다.

listen 포트는 그대로 둔채, accept 하고 나서 다른 포트로 통신하게 되는 이유가 이거였나..

[링크 : https://www.crocus.co.kr/544]

[링크 : https://www.joinc.co.kr/w/Site/Network_Programing/Documents/Poll]

'Linux API > network' 카테고리의 다른 글

recv 와 read 차이  (0) 2023.06.23
AF_PACKET로 link layer 열기  (0) 2022.06.09
ssl socket 예제  (0) 2022.03.25
TCP timeout  (0) 2020.09.29
UDS (Unix Domain Socket)  (0) 2020.09.01
Posted by 구차니
Linux API/network2022. 3. 25. 14:12

복붙하면 "와 ' 가 문제가 생기고

우분투 18.04 에서 빌드하면 client 쪽의 소스에서

SSLv3_client_method() 함수가 없다고 나오니, SSLv23_client_method 으로 바꾸어 주어야 한다.

[링크 : http://pchero21.com/?p=603]

 

실행하면 보안인증서 경로 문제로 실행이 안되는데 인증서는 어떻게 생성해야 하려나..

[링크 : https://m.blog.naver.com/espeniel/221845133507]

 

 

+ 빌드

$ sudo apt-get install libssl-dev

[링크 : https://stackoverflow.com/questions/43131708/fatal-error-openssl-rsa-h-no-such-file-or-directory]

 

-lssl 옵션을 주고 빌드하는데 아래와 같은 에러 발생시에는

/usr/bin/ld: /tmp/ccHIcKux.o: undefined reference to symbol 'ERR_print_errors_fp@@OPENSSL_1_1_0'
//usr/lib/x86_64-linux-gnu/libcrypto.so.1.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

 

-lcrytpo 까지 추가해주면 해결!

% gcc -o test test.c -L/usr/lib -lssl -lcrypto

[링크 : https://stackoverflow.com/questions/12917731/linking-issues-using-openssl-in-ubuntu]

 

+

nc 테스트

접속시 connection from이 뜨고

sadf를 입력하니 error가 나오며 접속이 종료된다.

$ ./srv
Enter PEM pass phrase:
Connection from 100007f, port 96c5
140278452101568:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:332:

 

$ nc localhost 1111

sadf

'Linux API > network' 카테고리의 다른 글

AF_PACKET로 link layer 열기  (0) 2022.06.09
linux tcp server listen accept connect  (0) 2022.05.11
TCP timeout  (0) 2020.09.29
UDS (Unix Domain Socket)  (0) 2020.09.01
raw socker과 promiscous mode  (0) 2019.07.03
Posted by 구차니
Linux API/network2020. 9. 29. 14:10

 

 

[링크 : https://www.joinc.co.kr/w/Site/Network_Programing/Documents/Sockettimeout]

[링크 : https://blog.cloudflare.com/ko/when-tcp-sockets-refuse-to-die-ko/]

'Linux API > network' 카테고리의 다른 글

linux tcp server listen accept connect  (0) 2022.05.11
ssl socket 예제  (0) 2022.03.25
UDS (Unix Domain Socket)  (0) 2020.09.01
raw socker과 promiscous mode  (0) 2019.07.03
리눅스 UDP 소켓  (0) 2019.05.24
Posted by 구차니
Linux API/network2020. 9. 1. 17:39

 

 

[링크 : https://blog.naver.com/jaelong191/221304232639]

[링크 : https://www.joinc.co.kr/w/Site/system_programing/IPC/Unix_Domain_Socket]

[링크 : https://en.wikipedia.org/wiki/Unix_domain_socket]

'Linux API > network' 카테고리의 다른 글

ssl socket 예제  (0) 2022.03.25
TCP timeout  (0) 2020.09.29
raw socker과 promiscous mode  (0) 2019.07.03
리눅스 UDP 소켓  (0) 2019.05.24
리눅스 TCP 소켓  (0) 2019.05.24
Posted by 구차니
Linux API/network2019. 7. 3. 13:30

음.. 두개는 연관이 없는 건가? 헷갈림

 

raw socket

sd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);

[링크 : https://www.tenouk.com/Module43a.html]

[링크 : http://naver.pages.kr/140042345641]

 

#define IPPROTO_TCP 6

#define IPPROTO_UDP 17

[링크 : https://unix.superglobalmegacorp.com/BSD4.4/newsrc/netinet/in.h.html]

 

promiscous mode

s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

[링크 : https://sangchul.kr/530]

[링크 : https://stackoverflow.com/questions/114804/reading-from-a-promiscuous-network-device]

 

#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */

[링크 : https://github.com/spotify/linux/blob/master/include/linux/if_ether.h]

 

 

PF_*, AF_* 차이(없다)

[링크 : http://blog.naver.com/PostView.nhn?blogId=l18400&logNo=60109296392]

 

AF_INET is used, if you want to communicate using Internet protocols: TCP or UDP.

AF_PACKET is used if you want to play with packets at the protocol level, i.e. you are implementing your own protocol. Only processes with effective UID 0 [root] or the capability CAP_NET_RAW may open packet sockets.

[링크 : https://www.quora.com/Whats-the-difference-between-the-AF_PACKET-and-AF_INET-in-python-socket]

'Linux API > network' 카테고리의 다른 글

TCP timeout  (0) 2020.09.29
UDS (Unix Domain Socket)  (0) 2020.09.01
리눅스 UDP 소켓  (0) 2019.05.24
리눅스 TCP 소켓  (0) 2019.05.24
linux udp cpp example  (0) 2019.05.16
Posted by 구차니
Linux API/network2019. 5. 24. 14:11

sento() 에 인자를 좀 바꾸어서 명령어줄 인자를 받으면 재미있긴 한데..

TCP 처럼 클라이언트 별로 accept 해주는 구조가 아니라

개별 클라이언트를 어떻게 구분해야 하지? 라고 고민중

 

server

// Server side implementation of UDP client-server model
#include 
#include 
#include 
#include 
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define PORT     8080
#define MAXLINE 1024

// Driver code
int main() {
        int sockfd;
        char buffer[MAXLINE];
        char *hello = "Hello from server";
        struct sockaddr_in servaddr, cliaddr;

        // Creating socket file descriptor
        if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
                perror("socket creation failed");
                exit(EXIT_FAILURE);
        }

        memset(&servaddr, 0, sizeof(servaddr));
        memset(&cliaddr, 0, sizeof(cliaddr));

        // Filling server information
        servaddr.sin_family = AF_INET; // IPv4
        servaddr.sin_addr.s_addr = INADDR_ANY;
        servaddr.sin_port = htons(PORT);

        // Bind the socket with the server address
        if ( bind(sockfd, (const struct sockaddr *)&servaddr,
                        sizeof(servaddr)) < 0 )
        {
                perror("bind failed");
                exit(EXIT_FAILURE);
        }

        while(1)
        {
        int len, n;
        n = recvfrom(sockfd, (char *)buffer, MAXLINE,
                                MSG_WAITALL, ( struct sockaddr *) &cliaddr,
                                &len);
        buffer[n] = '\0';
        printf("Client : %s\n", buffer);
//      sendto(sockfd, (const char *)hello, strlen(hello),
        sendto(sockfd, (const char *)buffer, strlen(buffer),
                MSG_CONFIRM, (const struct sockaddr *) &cliaddr,
                        len);
        printf("Hello message sent.\n");
        }
        return 0;
}

 

client

// Client side implementation of UDP client-server model
#include 
#include 
#include 
#include 
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define PORT     8080
#define MAXLINE 1024

// Driver code
int main(int argc, char **argv) {
        int sockfd;
        char buffer[MAXLINE];
        char *hello = "Hello from client";
        struct sockaddr_in       servaddr;

        // Creating socket file descriptor
        if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
                perror("socket creation failed");
                exit(EXIT_FAILURE);
        }

        memset(&servaddr, 0, sizeof(servaddr));

        // Filling server information
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(PORT);
        servaddr.sin_addr.s_addr = INADDR_ANY;

        int n, len;

//      sendto(sockfd, (const char *)hello, strlen(hello),
        sendto(sockfd, (const char *)argv[1], strlen(argv[1]),
                MSG_CONFIRM, (const struct sockaddr *) &servaddr,
                        sizeof(servaddr));
        printf("Hello message sent.\n");

        n = recvfrom(sockfd, (char *)buffer, MAXLINE,
                                MSG_WAITALL, (struct sockaddr *) &servaddr,
                                &len);
        buffer[n] = '\0';
        printf("Server : %s\n", buffer);

        close(sockfd);
        return 0;
}

 

[링크 : https://www.geeksforgeeks.org/udp-server-client-implementation-c/]

[링크 : https://www.geeksforgeeks.org/tcp-and-udp-server-using-select/]

 

+

[링크 : https://scrapsquare.com/notes/udp-length]

[링크 : https://en.wikipedia.org/wiki/User_Datagram_Protocol]

 

+

class (cpp) 기반 UDP socket 예제

[링크 : http://youngmok.com/udp-server-c-class-listening-thread/]

'Linux API > network' 카테고리의 다른 글

UDS (Unix Domain Socket)  (0) 2020.09.01
raw socker과 promiscous mode  (0) 2019.07.03
리눅스 TCP 소켓  (0) 2019.05.24
linux udp cpp example  (0) 2019.05.16
linux socket 관련  (0) 2015.01.22
Posted by 구차니
Linux API/network2019. 5. 24. 11:01

개념만 알지 써보진 않은 녀석이라.. 후 공부 해야겠네 ㅠㅠ

역시 공부는 돈받고 해야 제맛

 

테스트 삼아 SOCK_STREAM을 SOCK_DGRAM 으로 바꾸었는데

accept 하는 부분이 달라져야 하는지 정상작동을 하진 않는다.

(댓글들 보면 메모리 누수라던가 여러가지 문제가 넘치는 소스인듯)

그래도 서버 하나 실행하고 클라이언트 여러개 실행해도 각각 응답이 다르게 오는것 봐서는

내가 의도하는 그런 정상적인(!) 서버로 구동되는 건 맞는 듯 하니 일단 패스

 

server

/*
        C socket server example, handles multiple clients using threads
*/

#include
#include      //strlen
#include      //strlen
#include<sys/socket.h>
#include<arpa/inet.h>   //inet_addr
#include      //write
#include //for threading , link with lpthread

//the thread function
void *connection_handler(void *);

int main(int argc , char *argv[])
{
        int socket_desc , client_sock , c , *new_sock;
        struct sockaddr_in server , client;

        //Create socket
        socket_desc = socket(AF_INET , SOCK_STREAM , 0);
        if (socket_desc == -1)
        {
                printf("Could not create socket");
        }
        puts("Socket created");

        //Prepare the sockaddr_in structure
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons( 8888 );

        //Bind
        if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
        {
                //print the error message
                perror("bind failed. Error");
                return 1;
        }
        puts("bind done");

        //Listen
        listen(socket_desc , 3);

        //Accept and incoming connection
        puts("Waiting for incoming connections...");
        c = sizeof(struct sockaddr_in);


        //Accept and incoming connection
        puts("Waiting for incoming connections...");
        c = sizeof(struct sockaddr_in);
        while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
        {
                puts("Connection accepted");

                pthread_t sniffer_thread;
                new_sock = malloc(1);
                *new_sock = client_sock;

                if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) new_sock) < 0)
                {
                        perror("could not create thread");
                        return 1;
                }

                //Now join the thread , so that we dont terminate before the thread
                //pthread_join( sniffer_thread , NULL);
                puts("Handler assigned");
        }

        if (client_sock < 0)
        {
                perror("accept failed");
                return 1;
        }

        return 0;
}

/*
 * This will handle connection for each client
 * */
void *connection_handler(void *socket_desc)
{
        //Get the socket descriptor
        int sock = *(int*)socket_desc;
        int read_size;
        char *message , client_message[2000];

        //Send some messages to the client
        message = "Greetings! I am your connection handler\n";
        write(sock , message , strlen(message));

        message = "Now type something and i shall repeat what you type \n";
        write(sock , message , strlen(message));

        //Receive a message from client
        while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
        {
                //Send the message back to client
                write(sock , client_message , strlen(client_message));
        }

        if(read_size == 0)
        {
                puts("Client disconnected");
                fflush(stdout);
        }
        else if(read_size == -1)
        {
                perror("recv failed");
        }

        //Free the socket pointer
        free(socket_desc);

        return 0;
}

client

/*
        C ECHO client example using sockets
*/
#include       //printf
#include      //strlen
#include<sys/socket.h>  //socket
#include<arpa/inet.h>   //inet_addr
#include 

int main(int argc , char *argv[])
{
        int sock;
        struct sockaddr_in server;
        char message[1000] , server_reply[2000];

        //Create socket
        sock = socket(AF_INET , SOCK_STREAM , 0);
        if (sock == -1)
        {
                printf("Could not create socket");
        }
        puts("Socket created");

        server.sin_addr.s_addr = inet_addr("127.0.0.1");
        server.sin_family = AF_INET;
        server.sin_port = htons( 8888 );

        //Connect to remote server
        if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
        {
                perror("connect failed. Error");
                return 1;
        }

        puts("Connected\n");

        //keep communicating with server
        while(1)
        {
                printf("Enter message : ");
                scanf("%s" , message);

                //Send some data
                if( send(sock , message , strlen(message) , 0) < 0)
                {
                        puts("Send failed");
                        return 1;
                }

                //Receive a reply from the server
                if( recv(sock , server_reply , 2000 , 0) < 0)
                {
                        puts("recv failed");
                        break;
                }

                puts("Server reply :");
                puts(server_reply);
        }

        close(sock);
        return 0;
}

[링크 : https://www.geeksforgeeks.org/...-handling-multiple-clients-on-server-without-multi-threading/]

[링크 : https://stackoverflow.com/questions/31461492/client-server-multiple-connections-in-c]

 

1. Create socket
2. Bind to address and port
3. Put in listening mode
4. Accept connections and process there after.

[링크 : https://www.binarytides.com/server-client-example-c-sockets-linux/]

 

 

+

man page 보는데 특이하게 2번과 3번으로 두개가 있네?

설명 자체는 둘이 좀 달라서 어느게 어떤 차이가 있는지 좀 애매하다.

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

#define _GNU_SOURCE
            /* See feature_test_macros(7) */

#include <sys/socket.h>

int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);

[링크 : https://linux.die.net/man/2/accept]

 

#include <sys/socket.h>

int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);

[링크 : https://linux.die.net/man/3/accept]

 

 

'Linux API > network' 카테고리의 다른 글

raw socker과 promiscous mode  (0) 2019.07.03
리눅스 UDP 소켓  (0) 2019.05.24
linux udp cpp example  (0) 2019.05.16
linux socket 관련  (0) 2015.01.22
멀티캐스트 되는지 여부 확인  (0) 2014.11.21
Posted by 구차니