연결 통신을 위한 플러그인 만들기

소켓은 전송 공급자의 핸들입니다. SOCKET 형식입니다.
socket WSASocket 두 함수를 사용하여 소켓을 만들 수 있습니다.

  
  
  
  
  1. SOCKET socket( 
  2.   int af, 
  3.   int type, 
  4.   int protocol 
  5. ); 

 
서버 API 함수
1. 바인딩 bind
어떤 프로토콜의 플러그인을 만들면, 플러그인을 이미 알고 있는 주소로 연결해야 합니다

  
  
  
  
  1. int bind( 
  2.   SOCKET s, 
  3.   const struct sockaddr FAR* name, 
  4.   int   namelen 
  5. ); 
  6. //s  
  7.  
  8. SOCKET s; 
  9. SOCKADDR_IN tcpaddr; 
  10. int port = 5050; 
  11.  
  12. s = socket(AF_INET, SOCK_STREAM, IPPORTO_TCP); 
  13.  
  14. tcpaddr.sin_family = AF_INET; 
  15. tcpaddr.sin_port = htons(port); 
  16. tcpaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
  17.  
  18. bind(s, (SOCKADDR *)&tcpaddr, sizeof(tcpaddr)); 

오류가 발생하면 bind가 SOCKET 로 돌아갑니다.ERROR
 
2. listen 수신
다음은 감청 모드에 소켓을 넣는 것입니다.

  
  
  
  
  1. int listen( 
  2.   SOCKET s;//  
  3.   int backlog//  
  4. ); 

 
3. 연결 수신 accept
accept WSAaccept AcceptEx에서 연결 허용

  
  
  
  
  1. SOCKET accept( 
  2.   SOCKET s,// ,  
  3.   struct sockaddr FAR* addr,// SOCKADDR_IN  
  4.   int FAR* addrlen//SOCKADDR_IN  
  5. ); 

 
TCP/IP 연결을 적용할 수 있는 서버 작성

  
  
  
  
  1. #include <winsock2.h> 
  2. void main(void
  3.   WSAData wsaData; 
  4.   SOCKET  ListenSocket; 
  5.   SOCKET  NewSocket; 
  6.   SOCKADDR_IN ServerAddr; 
  7.   SOCKADDR_IN ClientAddr; 
  8.   int port = 5050; 
  9.   // winsock  
  10.   WSAStartup(MAKEWORD(2,2), &wsaData); 
  11.  
  12.   ListenSocket = socket(AF_INET, SOCK_STREAM, IPPORTO_TCP); 
  13.   ServerAddr.sin_family = AF_INET; 
  14.   ServerAddr.sin_port = htons(port); 
  15.   ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); 
  16.    
  17.   bind(ListenSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)); 
  18.    
  19.   listen(ListenSocket, 5); 
  20.    
  21.   NewSocket = accept(ListenSocket, (SOCKADDR*)&ClientAddr, &ClientAddrLen); 
  22.   //.. 
  23.  
  24.   closesocket(NewSocket); 
  25.   closesocket(ServerSocket); 
  26.   WSACleanup(); 

 
클라이언트 API 함수
TCP 상태: 모든 소켓의 초기 상태는 CLOSED입니다.클라이언트가 연결을 초기화하면 서버에 SYN 패키지가 전송되고 클라이언트는 소켓 상태를 SYNSENT.서버가 SYN 패키지를 받으면 SYN이 전송됩니다.ACK 패키지, 클라이언트가 ACK 패키지를 보내서 응답해야 합니다.서버가 SYN을 전송하지 않는 경우 클라이언트가 ESTABLISHED 상태로 소켓을 사용합니다.ACK 패키지는 클라이언트가 시간을 초과하여 CLOSED 상태로 돌아갑니다.
만약 서버의 플러그인이 로컬 인터페이스와 포트와 연결되어 위에서 감청을 진행한다면 플러그인 상태는 LISTEN입니다.클라이언트가 서버와 연결을 시도하면 서버는 SYN 패키지를 받고 SYN을 사용합니다ACK 패키지가 응답하면 서버 소켓 상태가 SYN 으로 바뀝니다.RCVD, 가장 좋은 클라이언트가 ACK 패키지를 보내면 서버 플러그인을 ESTABLISHED 상태로 설정합니다.
ESTABLISHED 상태가 되면 두 가지 방법으로 애플리케이션을 종료할 수 있습니다.만약 응용 프로그램이 닫는다면 주동적인 플러그인 닫기라고 한다.그렇지 않으면 수동적이다.사전 예방적으로 종료하면 FIN 패키지가 전송됩니다.응용 프로그램이 closesocket이나 shutdown을 호출할 때 통신 상대방에게 FIN 패키지를 보내고 플러그인 상태가 FIN 으로 바뀝니다WAIT_1.정상적인 상황에서 통신 상대방은 하나의 ACK 패키지로 응답하고 플러그인 상태는 FINWAIT_2.통신 상대방도 연결을 닫으면 FIN 패키지가 발송되고, 우리 기계는 ACK 패키지로 응답하며, 소켓 상태를 TIME 로 설정합니다.WAIT.
수동으로 닫히면 애플리케이션이 상대방으로부터 FIN 패키지를 받고 ACK 패키지로 응답합니다. 이 경우 애플리케이션의 소켓이 CLOSE 로 바뀝니다.WAIT 상태상대방이 이미 자신을 닫았기 때문에, 그것은 더 이상 데이터를 보내지 않는다.응용 프로그램은 연결이 꺼질 때까지 데이터를 계속 보낼 수 있다.터미널에 연결하려면 애플리케이션에서 자체 FIN 패키지를 실행하여 LAST 에 애플리케이션 소켓을 배치해야 합니다.ACK, 응용 프로그램이 상대방으로부터 ACK 패키지를 받으면, 그 플러그인은 CLOSEED 상태가 됩니다.
 
connect  
소켓 연결은 connect, WSAconnect, ConnectEx 함수를 호출하여 수행합니다.

  
  
  
  
  1. int connect( 
  2.   SOCKET s,// TCP  
  3.   const struct sockaddr FAR* name, 
  4.   int namelen 
  5. ); 

 
클라이언트 프레젠테이션:

  
  
  
  
  1. #include <winsock2.h> 
  2.  
  3. void main(void
  4.   WSADATA wsaData; 
  5.   SOCKET  s; 
  6.   SOCKADDR_IN addr; 
  7.   int port = 5050; 
  8.    
  9.   WSAStartup(MAKEWORD(2,2), &wsaData); 
  10.   s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
  11.   addr.sin_family = AF_INET; 
  12.   addr.sin_port = htons(port); 
  13.   addr.sin_addr.s_addr = inet_addr("123.123.123.123"); 
  14.   //... 
  15.   connect(s, (SOCKADDR*)&addr, sizeof(addr)); 
  16.   closesocket(s); 
  17.   WSACleanup(); 

 
데이터 전송
데이터 보내기 API send WSASend 함수
수신 데이터 API recv WSARecv 함수
한 가지 명심해야 한다. 수발 데이터와 관련된 모든 버퍼는 간단한char 형식, 즉 바이트에 대한 데이터에 속한다.
모든 송수신 함수에서 반환된 오류는 SOCKETERROR, WSAGetLastError를 사용하여 오류 정보를 얻을 수 있습니다.

  
  
  
  
  1. int send( 
  2.   SOCKET s,//  
  3.   const char FAR* buf,// ,  
  4.   int len,//  
  5.   int flags 
  6. ); 
  7. // ,send , SOCKET_ERRPR 

  
  
  
  
  1. int WSASend( 
  2.   SOCKET s,//  
  3.   LPWSABUF lpBuffer,// WSABUF  
  4.   DWORD  dwBufferCount,// WSABUF  
  5.   LPDWORD  lpNumberOfBytesSend,// DOWRD ,  
  6.   DWORD  dwFlags, 
  7.   LPWSAOVERLAPPED lpOverLapped, 
  8.   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine 
  9. ); 
  10. //lpNumberOfBytesSend , 0, SOCK_ERROR 

함수 WSASendDisconnect 보내기
이 함수는 매우 특수해서 일반적으로 쓰지 않는다

  
  
  
  
  1. int WSASendDisconnect( 
  2.   SOCKET s, 
  3.   LPWSABUF lpOutboundDisconnectData 
  4. ); 

함수 WSASenddisconnect는 처음에 소켓을 닫은 상태로 설정하고 포트의 데이터를 전송합니다
 
연결을 위한 플러그인에서recv를 통해 데이터를 수신합니다

  
  
  
  
  1. int recv( 
  2.   SOCKET s,//  
  3.   char FAR* buf,//  
  4.   int len,//  
  5.   int flags 
  6. ); 

가능한 한 모든 데이터를 자신의 버퍼에 복사하고 그곳에서 데이터를 조작하세요.
제공된 버퍼보다 데이터가 커질 때 버퍼는 가능한 한 데이터를 채웁니다. 이 때 recv 호출은 WSAEMSGSIZE 오류가 발생합니다.메시지 크기의 오류는 메시지를 위한 프로토콜에서 발생하고, 흐름 프로토콜은 전송된 데이터를 캐시하여 프로그램에 필요한 데이터를 최대한 되돌려줍니다. 비록 연결된 데이터가 제공된 버퍼보다 크더라도 흐름 프로토콜에 대해 WSAEMSGSIZE 오류가 발생하지 않습니다.

  
  
  
  
  1. int WSARecv( 
  2.   SOCKET s,//  
  3.   LPWSABUF lpBuffers,//  
  4.   DWORD dwBufferCount, 
  5.   LPWORD lpNumberOfBytesRecvd, //
  6.   LPWORD lpFlags, 
  7.   LPWSAOVERLAPPED lpOverlapped, 
  8.   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine 
  9. ); 

 
연결 끊기
플러그인 연결이 완료되면, 플러그인을 닫고, 이 플러그인에 연결된 모든 자원을 방출해야 합니다.shutdown으로 연결을 닫고closesocket을 이용하여 플러그인에 연결된 자원을 방출합니다.

  
  
  
  
  1. int shutdown( 
  2.   SOCKET s, 
  3.   int  how 
  4. ); 
  5. //how  SD_RECEIVE,SD_SEND,SD_BOTH 
  6. //SD_RECEIVE  
  7. //SD_SEND  
  8. //SD_BOTH  

closesocket은 플러그인을 닫는 데 사용됩니다

  
  
  
  
  1. int closesocket(SOCKET s); 

 

좋은 웹페이지 즐겨찾기