윈도우 소켓프로그래밍 관련 질문있습니다.

201413694의 이미지

몇일전에 과제때문에 질문올렸던 학생입니다.

윈도우 소켓프로그래밍 관련이 질문이 있습니다.

과제 조건
1.PC와 장비(회사내 장비)와 소켓 프로그래밍을 통해 통신을 한다.

2.PC에서 장비로 8바이트{0xA0 0x03 0xA0 0x03 0x01 0x01 0x00 0x0E}를 전송한다.

3.장비의 ip는 192.168.0.11 포트번호는 5001이다.

4.장비는 8바이트의 정보를 받아 162바이트의 통신 패킷을 전송한다.

5.PC에서 162바이트가 잘왔는지 확인한다.
-----------------------------------------------
이후 162바이트를 파싱을 한다.

현재상황
char hex[]="A003A0030101000E"를 보냈더니
0x00001100 의 데이터크기를 받아 바이트로 환산하니 4392바이트를 받았습니다.

질문사항
1.PC에서 8바이트를 보내라할때
char hex[]="A003A0030101000E"로 보냈을떄 보내는 바이트는 16바이트입니다.
또한 받게되는 바이트 역시 16바이트입니다.(제가 원하는건 8바이트를 보내고 162바이트를 받는것입니다)

1-1)문자열로 데이터를 보내는게 아니라 정수형으로 보내야하는건가요?

1-2)만약 보낸다면 길이를 고려했을떄 변수1,변수2로 나누어서 보내야하나요?

1-3)아니면 배열로 {0xA0 0x03 0xA0 0x03 0x01 0x01 0x00 0x0E}을 선언해서 send로 보내야하는건가요?

2.서버 소스에서는 INADDR를 통해 모든 아이피를 받을 수 있게 하는건 이해가 됩니다.
클라이언트 소스에서는 "127.0.0.1"을 사용하면 자신의 PC에서 즉 cmd창 2개로 띄어서 하는 통신만 가능한건가요?

3.8바이트를 보냈을때 문자열이 아니라 데이터라서 장비가 데이터를 받고 8바이트가 아닌 162바이트를 내보내는 건가요?

4.구글링을 통해서 확보하는 소스코드 중에 connect() 대상 컴퓨터에 연결을 할 수 없다는 메시지창이 나옵니다. 방화벽은 모두 끈 상태인데 소스코드의 문제인가요?

5.소켓 프로그래밍을 독학하기에 추천해주실만한 책이나 사이트 혹시 알려주실 수 있나요?

//서버   순서:원속초기화-소켓생성-(데이터통신:bind,listen,accept)-소켓해제-원속종료
#include<stdio.h> 
#include<stdlib.h>
#include<string.h>
#include<winsock2.h>   //리눅스 소켓프로그래밍과는 다르게 윈도우 소켓프로그래밍에서 이것을 선언해야됨
#pragma comment(lib,"ws2_32.lib")
#define BUFSIZE 2018
 
void ErrorHandling(char* message);
 
size_t len_test(char* s);
 
size_t len_test(char* s) {
	return strlen(s);
}
 
int main(int argc, char *argv[])
{
 
	//원속 소켓프로그래밍에서 사용자가 만드는 구조체를 제외하고 필수적으로 만들어 놓은 구조체들
	SOCKET sock, clientsock; //실제 통신을 위한 소켓 구조체 
	WSADATA wsa;    //윈속 초기화 WSAStartup 함수 호출을 위한 구조체선언
	struct sockaddr_in sockinfo, clientinfo;  //소켓에 IP/PORT를 할당(bind) 시키기 위해 중간에 주소를 저장해줄 구조체
					 //AF_INET(인터넷 주소 체계)를 사용해서 Sockaddr_in 구조체를 사용
	int clientsize;
	//클라이언트 소켓 변수 clientsock과 clientinfo 그리고  int clientsize
	char message[] = "A003A0030101000E";
	printf("서버에서 보내는 메시지의 크기 %u\n", len_test(message));
 
 
 
	long HEX1 = 0xA003A003;
	long HEX2 = 0x0101000E;
 
 
 
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)  //MAKEWORD(2,2)는 매크로 함수
		ErrorHandling("Winsock DLL 실패");
	//윈도우 소케프로그래밍을 사용하기 위해서 Winsock.dll 파일로드 & WSACleanup 함수로 해제
	//int WSAStartup(WORD ___,LPWSADATA ___);  초기화 함수 포맷
	//               원속버전,WSAData의 포인터를 전달하여 시스템에 제공하는 원속 정보를 얻어옴(구조체 주소를 전달)
	//원속 초기화 작업 완료
 
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  //  [성공시 소켓 핸들,실패시 INVALUID_SOCKET]
			//소켓생성함수로써 af,type,protocol
			//Af 주소영역 지정:인터넷 영역,IPX영역 그외 통신영역,보통 인터넷 통신이라서 AF_INET
			//Type:  연결지향 TCP->SOCK_STREAM   비연결지향 UDP->SOCK_DRAME,TCP/IP소켓 프로그래밍이므로 전자를 선택
			//Protocol TCP->IPPROTO_TCP   UDP->IPPROTO_UDP
 
	if (sock == INVALID_SOCKET)
		ErrorHandling("Soecket 생성 실패");
	//HANDLE(핸들) 운영체제는 자신이 관리하는 자원이나 정보를 보호하기 위해서 
	//자신이 관리하는 자원이나 정보의 실질적인 주소를 응용 프로그램에게 알려주지 않고 
	//그것을 암시하는 값만 전달하는 방식을 사용
	//소켓 프로그래밍에서 성공시 0값으로 리턴하는 함수와 핸들값으로 리턴하는 함수가 있다.
	//반환 값을 확인할 떄는 INVALID_SOCKET을 이용
	//핸들은 프로그램 내부에서 처리하는 암시적인 값,따라서 변수선언하여 저장,INVALID_SOCK 를 사용해서 확인
	//소켓 생성 작업 완료
 
	memset(&sockinfo, 0, sizeof(SOCKADDR_IN));  //★sizeof(sockinfo) ?
	sockinfo.sin_family = AF_INET; //주소체계  AF_INET,AF_INET6,AF_LOCAL
	sockinfo.sin_port = htons(5001);  //★ htons(atoi("9190"));
	sockinfo.sin_addr.s_addr = htonl(INADDR_ANY);  //ip를 지정함
				   //서버 입장에서는 모든 인터넷 주소로 클라이언트를 대기해야하므로 INADDR_ANY 0.0.0.0 주소를 사용
				  //모든 사용 가능한 주소로 부터 대기
				  //소켓 주소 구조체
 
	if (bind(sock, (SOCKADDR*)&sockinfo, sizeof(sockinfo)) == SOCKET_ERROR) //[성공시 0,실패시 SOCKET_ERROR]
		ErrorHandling("bine 실패");
	//   소켓값,(SOCKADDR*)&소켓주소 구조체 저장값,sizeof(소켓주소 구조체 저장값)
 
	if (listen(sock, 5) == SOCKET_ERROR) //[성공시 0,실패시 SOCKET_ERROR]
		ErrorHandling("listen 실패");
	printf("클라이언트로부터 접속을 기다리고 있습니다...\n");
	//대기상태를 의미
	//list(SOCKET,backlog)  소켓 생서시 만들어서 저장했던 소켓 핸들값과 통로값
 
	clientsize = sizeof(clientinfo);
	clientsock = accept(sock, (SOCKADDR*)&clientinfo, &clientsize);  //  [성공시 소켓 핸들,실패시 INVALUID_SOCKET]
			   //서버 프로그램 안에 클라이언트 연결 소켓을 만듬
			   //서버소켓,(SOCKADDR*)&클라이언트주소값,&클라이언트 주소값 사이즈
	if (clientsock == INVALID_SOCKET)  //소켓핸들값이라서 INVALID_SOCKET로 확인
		ErrorHandling("accept 실패");
 
	send(clientsock, message, sizeof(message), 0);
 
	send(sock, &HEX1, sizeof(HEX1), 0);
	send(sock, &HEX2, sizeof(HEX2), 0);
 
	//send(clientsock, hex, sizeof(hex), 0);
 
 
 
	closesocket(sock);
	closesocket(clientsock);
	printf("성공\n");
	WSACleanup();
 
}
 
void ErrorHandling(char *message) {
	WSACleanup();
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}
 
//클라이언트 순서:초기화-소켓생성-connect-소켓해제-원속 종료
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h>
#include<winsock2.h> 
#pragma comment(lib,"ws2_32.lib")
#define BUFSIZE 2048
 
void ErrorHandling(char *message);
 
 
 
int main(int argc, char *argv[])
//int argc는 메인함수에 전달되는 데이터의 갯수,argv는 문자열
//char* argv[]는 메인함수에 전달되는 실제적인 데이터로 char형 포인트 배열로 구성
{
	SOCKET clientsock;  // 클라이언트 프로그램 소켓 생성 
	WSADATA wsa;
	struct sockaddr_in sockinfo; // 서버 연결 할 주소 구조체 생성 
 
	char message[BUFSIZE]; // recv 함수 메시지 받을 배열 선언 
 
	int strlen; // recv 리턴 값 저장 할 변수 선언  
 
	long HEX1 = 0xA003A003;
	long HEX2 = 0x0101000E;
	long strlen1;
	long strlen2;
 
 
	if (argc != 3) // 입력 ( IP , PORT ) 가 입력되지 않을 때 오류 표시,2개를 입력받았고 +1을 해서 3이 되야 정상
	{
		printf("Usage : %s <IP> <PORT> \n", argv[0]);
		exit(1);
	}
 
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
		ErrorHandling("Winsock DLL error");
 
	clientsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (clientsock == INVALID_SOCKET)
		ErrorHandling("Soecket 생성 실패");
 
	memset(&sockinfo, 0, sizeof(sockinfo)); // 주소 구조체 함수 초기화 
	sockinfo.sin_family = AF_INET;
	sockinfo.sin_port = htons(atoi(argv[2])); // 포트를 두 번째로 입력 받음
			   //★ htons(atoi("9190");  
	sockinfo.sin_addr.s_addr = inet_addr("127.0.0.1"); //inet_addr(argv[1]); // IP를 첫 번째로 입력 받음   //sdl검사해제,여기서 입력하는 ip는 서버의 ip주소
 
 
	if (connect(clientsock, (SOCKADDR*)&sockinfo, sizeof(sockinfo)) == SOCKET_ERROR)  //[성공시 0,실패시 SOCKET_ERROR]
			  // 서버 측에 연결 요청 
		ErrorHandling("accept 실패");
	//          클라이언트소켓,(SOCKADDR*)&서버주소구조체,sizeof(서버주소구조체)
 
	strlen = recv(clientsock, message, sizeof(message) - 1, 0);  //메시지를 수신하여 저장하는 함수
	if (strlen == -1) // recv 함수 반환 값이 -1이면 메시지 수신 실패 
		ErrorHandling("message 실패");
 
 
 
	printf("받은 데이터는 16진수로 0x%08X 입니다.\n", htons(strlen));
	printf("받은 데이터는 십진수로 %d 입니다.\n", htons(strlen));
 
 
	printf(" Server say: %s \n", message); // 수신 된 메시지 표시 
 
 
 
 
	closesocket(clientsock);  //[성공시 0,실패시 SOCKET_ERROR]
	WSACleanup();
}
 
void ErrorHandling(char *message) {
 
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}
 
 
 
<\code>

shint의 이미지

send(소켓, 데이터, 크기, 플래그); 함수에 보내는 크기가 있습니다.
1 바이트씩 보내서 확인해 보세요.

char a;
a = 'a';
send(소켓, a, 1, 0);

char b[2];
b[0] = 'a';
b[1] = 'b';
send(소켓, b, 2, 0);

char c[3];
c[0] = 'a';
c[1] = 'b';
c[2] = 'c';
send(소켓, c, 3, 0);

char d[4];
d[0] = 'a';
d[1] = 'b';
d[2] = 'c';
d[3] = 0x00; //문자열 사용시. 문자열의 마지막을 구분하기 위한 0x00 NULL 데이터
send(소켓, d, 3, 0);
strcpy(&d[0], "123");

char e[3];
strncpy(&e[0], "123", 3); //3 바이트만 복사

char d[3];
memcpy(&f[0], "123", 3); //3 바이트만 복사

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

201413694의 이미지

답변감사합니다

karkayan의 이미지

클라이언트에서

printf("받은 데이터는 16진수로 0x%08X 입니다.\n", htons(strlen));
printf("받은 데이터는 십진수로 %d 입니다.\n", htons(strlen));

여기서 strlen은 recv 함수의 반환값으로, htons 함수를 적용하면 안됩니다. htons 를 빼고 그냥 출력하세요.
htons 함수의 역할을 이해하고 싶으시면 endian을 검색해보세요.

1. 이건 서버랑 클라이언트 정해야 할 문제네요. 장비에 이미 기존의 서버프로그램이 있는 건가요? 아니면 위의 서버프로그램을 장비에서 실행을 할건가요? 전자라면 기존 서버가 어떤 데이터를 받는지를 알아야 할테고, 후자라면 정수든 문자열이든 아무거나 편한대로 쓰면 됩니다.
2. 127.0.0.1은 자신의 pc를 나타내는 ip주소입니다. 다른 컴퓨터로 연결하려면 해당 컴퓨터의 ip주소를 사용해야 합니다. 현재 클라이언트는 무조건 127.0.0.1로 연결하도록 되어 있네요.
3. 질문의 의미를 모르겠네요.
4. 위의 클라이언트 코드를 말하는 건가요? 일단 connect 부분까지는 별 문제는 없어 보입니다.
올바른 ip를 사용하고 있는 건지 다시 확인해보세요. telnet 같은 걸 이용해서 서버 해당 포트에 연결이 가능한지도 테스트해보세요.
5. ms 사이트의 예제 코드를 참조하시는 것도 좋을 것 같습니다. https://docs.microsoft.com/en-us/windows/desktop/winsock/getting-started-with-winsock

201413694의 이미지

1.서버가 어떤 데이터를 받는지:0xA0 0x03 0xA0 0x03 0x01 0x01 0x00 0x0E 패킷을 보내는건데 8바이트니까 A0003A0030101000E 맞는건가요?
2.소스코드에서 127.0.0.1 과 inet_addr(argv[1]); 로 비교했더니 127.0.0.1이 되는걸로 보아 제가 클라이언트 맞습니다.
3.서버로 8바이트를 보내고(=랜선으로 다이렉트로 PC와 연결된 장비에 8바이트를 보내고) 장비에서 162바이트를 받아내라는데 저도 이해가 안갑니다.
답변 감사합니다.

라스코니의 이미지

리눅스의 경우 nc 라는 커맨드로 쉽게 상대방 ip에 뭔가 보낼 수 있습니다.
nc를 이용해서 8 바이트를 장비에 보내보시고, wireshark로 네트워크 패킷을 모니터링해서 장비 쪽이 162 바이트를 실제로 보내는지 확인해 보세요.

201413694의 이미지

이 경우는 장비쪽에 문제가 있는건가요?
빨간색으로 나오면 문제가 있다는걸로 들었습니다.

댓글 첨부 파일: 
첨부파일 크기
Image icon 제목 없음.png162.6 KB
라스코니의 이미지

RST, ACK가 뜨는 것을 보니 어느 한쪽에서 connect가 되지 않은 것으로 보이는데 장비쪽에 ping이 되나요? 장비쪽 포트가 open/listen 상태로 있는지 확인해 보세요.

shint의 이미지

src port = 55392
dst port = 8193
포트 번호가 다른거 같네요.

웹 브라우저 - 접속 확인
http://192.168.0.11:5001

텔넷 - 접속 확인
telnet 192.168.0.11 5001

Hex to ASCII text converter 헥사값을 문자로 변환하는 사이트 - 텟넷에서 붙여넣기 될 수 도 있겠네요. ㅇ_ㅇ;;
https://www.rapidtables.com/convert/number/hex-to-ascii.html

HEX A0
DEC 160
OCT 240
BIN 1010 0000
 
HEX 03
DEC 3
OCT 3
BIN 0011
 
HEX 01
DEC 1
OCT 1
BIN 0001
 
HEX 0E
DEC 14
OCT 16
BIN 1110
 
A0 03 A0 03 01 01 00 0E
  

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

shint의 이미지

//랜선
- 직접 연결 : 크로스 케이블 (4가닥에 선 위치가 반대)
- 간접 연결 : 공유기 허브

//IP 확인
- ipconfig 윈도우
- ifconfig 리눅스

//네트워크 장비의 주소 정보 얻는 방법
- arp -a

//포트 상태 정보 얻는 방법
- netstat -na

//접속 완료
장비 ip 192.168.0.11
포트번호 5001
connect(소켓, 소켓구조체, 소켓구조체 크기)

//전송 완료
char data[8];
data[0] = 0xA0;
data[1] = 0x03;
data[2] = 0xA0;
data[3] = 0x03;
data[4] = 0x01;
data[5] = 0x01;
data[6] = 0x00;
data[7] = 0x0E;
send(소켓, 데이터 배열, 데이터 크기, 플래그);

//받기 완료
char data[1024];
int r;
r = recv(소켓, 데이터 배열, 데이터 크기, 플래그);

//받은 데이터 출력
r = 받은 데이터 갯수
data = 받은 데이터값
printf("받은 데이터 갯수 : %d\n", r);
printf("받은 데이터값 : %s\n", data);
int i;
for(i=0; i<1024; i++)
{
printf("받은 데이터값 1 바이트씩 출력 : %x\n", data[i]); //16진수 헥사값 출력
// printf("받은 데이터값 1 바이트씩 출력 : %c\n", data[i]); //char 형 출력
}

1 byte 바이트 단위 == 1 char == 8 bit 비트 == 0x00 ~ 0xFF == unsigned 0 ~ 255 == signed -128 ~ 127

[C++ 정리] 자료형의 크기 및 범위
http://myblog.opendocs.co.kr/archives/1230

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

201413694의 이미지

답변감사합니다

201413694의 이미지

제가 사용하는 PC와 장비간의 소켓통신
1.장비의 ip는 192.168.0.11 이고 이를 http://192.168.0.11에서 다른 정보까지 알아봤습니다.
pc ip를 192.168.0.10 포트번호는 8193
장비 ip는 192.168.0.11 포트번호는 5001
192.168.0.11으로의 핑은 잘 나갑니다.

장비(192.168.0.11)에서 PC(192.168.0.10)으로의 전송은 오류가 없지만 장비쪽 포트번호가 랜덤입니다.
PC(192.168.0.10)에서 장비(192.168.0.11)으로의 전송은 오류가 생기고 장비쪽 포트번호가 랜덤입니다.
이 상황에서 장비쪽에 문제가 있는건가요?
1)제 생각에는 장비쪽 포트번호가 5001으로 사용되지 않아서 문제가 되는것 같은데
cmd창에 클라이언트 응용프로그램 넣고 192.168.0.11 5001 으로 연결되는것이 아닌가요?
2)아니면 수식은 맞지만 따로 장비 포트를 여는 작업이 필요한건가요?
(장비와의 연결문제로 162바이트 전송을 못받습니다.)

혹시 해서 코드도 같이 올립니다.

#include <Winsock2.h>
 
#include <stdlib.h>
 
#include <stdio.h>
 
 
 
#define BUFSIZE 512
 
 
 
int main()
 
{
 
   int retval;
 
 
 
   // 윈속초기화
 
   WSADATA wsa;
 
   if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
 
          return -1;
 
 
 
   // socket()
 
   SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
 
   if(listen_sock ==  INVALID_SOCKET) printf("소켓() 에러염");
 
 
 
   // bind()
 
   SOCKADDR_IN serveraddr;
 
   ZeroMemory(&serveraddr, sizeof(serveraddr));
 
   serveraddr.sin_family = AF_INET;
 
   serveraddr.sin_port = htons(5001);
 
   serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
   retval = bind(listen_sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr)); // connect가 아니라 bind
 
   if(retval == SOCKET_ERROR) printf("바인딩() 에러염");
 
 
 
   // listen()
 
   retval = listen(listen_sock, SOMAXCONN);
 
   if(retval == SOCKET_ERROR) printf("리슨() 에러염");
 
 
 
   // 데이터 통신에 사용할 변수
 
   SOCKET client_sock;
 
   SOCKADDR_IN clientaddr;
 
   char buf[BUFSIZE + 1];
 
   int addrlen;
 
 
 
   // 서버와 데이터 통신
 
   while(1)
 
   {
 
      // accept()
 
      addrlen = sizeof(clientaddr);
 
      client_sock = accept(listen_sock, (SOCKADDR*)&clientaddr, &addrlen);
 
      if (client_sock == INVALID_SOCKET){
 
              printf("accept() 에러\n");
 
              continue;
 
      }
 
      printf ("TCP 서버, 클라이언트 접속 : IP 주소 = %s, 포트번호 = %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
 
 
 
      // 클라이언트와 데이터 통신
 
      while(1)
 
      {
 
          retval = recv(client_sock, buf, BUFSIZE, 0);
 
          if (retval == SOCKET_ERROR)
 
         {
 
             printf("수신() 에러\n");
 
             break;
 
          }
 
          else if (retval == 0)
 
                 break;
 
 
 
          // 받은 데이터 출력
 
          buf[retval] = '\0';
 
          printf("[TCP /%s:%d] %s\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), buf);
 
 
 
          // 데이터 보내기
 
          retval = send(client_sock, buf, retval, 0);
 
          if (retval == SOCKET_ERROR)
 
         {
 
             printf("송신() 에러\n");
 
             break;
 
          }
 
      }
 
 
 
      // closesocket()
 
      closesocket(client_sock);
 
      printf("TCP 서버, 클라이언트 종료 : IP 주소 = %s, 포트번호 = %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
 
   }
 
 
 
   closesocket(listen_sock);
 
 
 
   // 윈속 종료
 
   WSACleanup();
 
   return 0;
 
}
 
#include <Winsock2.h>
 
#include <stdlib.h>
 
#include <stdio.h>
 
 
 
#define BUFSIZE 512
 
 
 
// 사용자 정의 데이터 수신 함수
 
int recvn(SOCKET s, char *buf, int len, int flags)
 
{
 
    int received;
 
    char *ptr = buf;
 
    int left = len;
 
 
 
    while (left > 0)
 
    {
 
       received = recv(s, ptr, left, flags);
 
       if (received == SOCKET_ERROR)
 
            return SOCKET_ERROR;
 
       else if (received == 0)
 
               break;
 
       left -= received;
 
       ptr += received;
 
    }
 
 
 
   return (len - left);
 
}
 
 
 
int main()
 
{
 
   int retval;
 
 
 
   // 윈속초기화
 
   WSADATA wsa;
 
   if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
 
          return -1;
 
 
 
   // socket()
 
   SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
 
   if(sock ==  INVALID_SOCKET) printf("소켓() 에러염");
 
 
 
   // connect()
 
   SOCKADDR_IN serveraddr;
 
   ZeroMemory(&serveraddr, sizeof(serveraddr));
 
   serveraddr.sin_family = AF_INET;
 
   serveraddr.sin_port = htons(5001);
 
   serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
 
   retval = connect(sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
 
   if(retval == SOCKET_ERROR) printf("연결() 에러염");
 
 
 
   // 데이터 통신에 사용할 변수
 
   char buf[BUFSIZE + 1];
 
   int len;
 
 
 
   // 서버와 데이터 통신
 
   while(1)
 
   {
 
      // 데이터 입력
 
      ZeroMemory(buf, sizeof(buf));
 
      printf("\n보낼데이터");
 
      if (fgets(buf, BUFSIZE+1, stdin) == NULL)
 
              break;
 
 
 
      // '\n' 문자 제거
 
      len = strlen(buf);
 
      if (buf[len - 1] == '\n')
 
        buf[len - 1] = '\0';
 
      if (strlen(buf) == 0)
 
        break;
 
 
 
      // 데이터 보내기
 
      retval = send(sock, buf, strlen(buf), 0);
 
      if (retval == SOCKET_ERROR)
 
      {
 
          printf("송신() 에러");
 
          break;
 
       }
 
      printf ("TCP 클라이언트 %d 바이트를 보냈습니다.", retval);
 
 
 
      // 데이터 받기
 
      retval = recvn(sock, buf, retval, 0);
 
      if (retval == SOCKET_ERROR)
 
      {
 
          printf("수신() 에러");
 
          break;
 
       }
 
       else if (retval == 0)
 
             break;
 
 
 
       // 받은 데이터 출력
 
       buf[retval] = '\0';
 
       printf("TCP 클라이언트 %d 바이트를 받았습니다.", retval);
 
       printf("받은 데이터 %s", buf);
 
    }
 
 
 
    // closesocket()
 
    closesocket(sock);
 
 
 
    // 윈속 종료
 
    WSACleanup();
 
     return 0;
 
}


댓글 첨부 파일: 
첨부파일 크기
Image icon 합체.png437.57 KB
shint의 이미지

ㅇ_ㅇ;;
shintx@nate.com

- 장비 업체에도 문의해보시구요.

//텔넷으로 HEX 값 문자로 보내는 방법도 있는거 같네요.
telnet server port << EOF
\x0B\x84\x31\x32\x33\x34\x35\x36\x37\x38\x00
more commands
more commands
quit
EOT

How to send a Hex message to server (Php and CLI)
https://community.spiceworks.com/topic/721790-how-to-send-a-hex-message-to-server-php-and-cli

telnet client - output hexadecimal network traffic on debian
https://unix.stackexchange.com/questions/81937/telnet-client-output-hexadecimal-network-traffic-on-debian

telnet> set netdata
Will print hexadecimal representation of network traffic.
telnet> set termdata
Will print hexadecimal representation of terminal traffic.

Putty
https://learn.adafruit.com/windows-tools-for-the-electrical-engineer/serial-terminal

windows 10에서 telnet 사용하기
https://opentutorials.org/module/2160/12506

윈도우7(Windows7)에서 텔넷(Telnet) 설치하기
http://ooz.co.kr/75

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

201413694의 이미지

답변감사합니다

201413694의 이미지

네트워크장비에서 연결포트가 5001이라서 서버&클라이언트 코딩에 5001을 넣었는데 와이어샤크 분석결과 8193(PC쪽 포트로 예상됨,네트워크장비에서 기계 ip 192.168.0.10 /포트 8193)은 고정값으로 받지만 다른 쪽은 5xxxx 와 같이 랜덤값으로 받습니다. 코딩에 문제가 있는건가요?

댓글 첨부 파일: 
shint의 이미지

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.