Tcp

基于连接的Tcp编程.

 

代码注释,如下:

  
  
  
  
  1. #include <stdio.h>  
  2. #include <winsock2.h>  
  3. #pragma comment(lib,"WS2_32.lib")  
  4.  
  5. #define BUF_SIZE 64  
  6.  
  7. int main()  
  8. {  
  9.     WSADATA wsadata; //包含DLL期望程序使用的版本和支持的最高版本等字段  
  10.     int retVal;  
  11.  
  12.     SOCKET sServer;  
  13.     SOCKET sClient;  
  14.     char buf[BUF_SIZE];  
  15.  
  16.     //  
  17.     retVal=WSAStartup(MAKEWORD(2,2),&wsadata);  
  18.     if(retVal != 0)  
  19.     {  
  20.         printf("WSAStartup failed!\n");  
  21.     }  
  22.  
  23.     //创建套接字  
  24.     sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);  
  25.     if(sServer == INVALID_SOCKET)  
  26.     {  
  27.         printf("socket failed!\n");  
  28.  
  29.         WSACleanup();  
  30.         return -1;  
  31.     }  
  32.  
  33.     //绑定套接字  
  34.     SOCKADDR_IN addrServ;  
  35.     addrServ.sin_family=AF_INET; //套接字属于协议族TCP/IP  
  36.     addrServ.sin_port=htons(4999);  
  37.     addrServ.sin_addr.S_un.S_addr=INADDR_ANY;  
  38.  
  39.     retVal=bind(sServer,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));  
  40.     if(retVal == SOCKET_ERROR)  
  41.     {  
  42.         printf("bind failed!\n");  
  43.  
  44.         closesocket(sServer);  
  45.         WSACleanup();  
  46.         return -1;  
  47.     }  
  48.  
  49.     //  
  50.     retVal=listen(sServer,1);  
  51.     if(retVal == SOCKET_ERROR)  
  52.     {  
  53.         printf("listen failed!\n");  
  54.  
  55.         closesocket(sServer);  
  56.         WSACleanup();  
  57.         return -1;  
  58.     }  
  59.  
  60.     //等待客户端的连接请求  
  61.     SOCKADDR_IN addrClient;  
  62.     int len=sizeof(SOCKADDR_IN);  
  63.  
  64.     sClient=accept(sServer,(LPSOCKADDR)&addrClient,&len); //返回一个新的套接字句柄  
  65.     if(sClient == INVALID_SOCKET)  
  66.     {  
  67.         printf("accept failed!\n");  
  68.  
  69.         closesocket(sServer);  
  70.         WSACleanup();  
  71.         return -1;  
  72.     }  
  73.  
  74.     //接收数据  
  75.     ZeroMemory(buf,BUF_SIZE);  
  76.  
  77.     retVal=recv(sClient,buf,BUF_SIZE,0);  
  78.     if(retVal == SOCKET_ERROR)  
  79.     {  
  80.         printf("recv failed!\n");  
  81.  
  82.         closesocket(sClient);  
  83.         closesocket(sServer);  
  84.         WSACleanup();  
  85.         return -1;  
  86.     }  
  87.  
  88.     //  
  89.     printf("Server receives data: ");  
  90.     printf("%s\n",buf);  
  91.  
  92.     //  
  93.     closesocket(sClient);  
  94.     closesocket(sServer);  
  95.     WSACleanup();  
  96.     return 0;  
  97. }  

 

  
  
  
  
  1. //Client.cpp  
  2. #include <stdio.h>  
  3. #include <winsock2.h>  
  4. #pragma comment(lib,"WS2_32.lib")  
  5.  
  6. #define BUF_SIZE 64  
  7.  
  8. int main()  
  9. {  
  10.     WSADATA wsadata;  
  11.     int retVal;  
  12.  
  13.     SOCKET sClient;  
  14.     char buf[BUF_SIZE];  
  15.  
  16.  
  17.     //加载套接字DLL  
  18.     retVal=WSAStartup(MAKEWORD(2,2),&wsadata);  
  19.     if(retVal != 0)  
  20.     {  
  21.         printf("WSAStartup failed!\n");  
  22.     }  
  23.  
  24.     //创建套接字  
  25.     sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);  
  26.     if(sClient == INVALID_SOCKET)  
  27.     {  
  28.         printf("socket failed!\n");  
  29.  
  30.         WSACleanup();  
  31.         return -1;  
  32.     }  
  33.  
  34.     //  
  35.     SOCKADDR_IN addrServ;  
  36.     addrServ.sin_family=AF_INET; //套接字属于协议族TCP/IP  
  37.     addrServ.sin_port=htons(4999);  
  38.     addrServ.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");  
  39.  
  40.     retVal=connect(sClient,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));  
  41.     if(retVal == SOCKET_ERROR)  
  42.     {  
  43.         printf("connect failed!\n");  
  44.  
  45.         closesocket(sClient);  
  46.         WSACleanup();  
  47.         return -1;  
  48.     }  
  49.  
  50.     //发送数据  
  51.     ZeroMemory(buf,BUF_SIZE);  
  52.     strcpy(buf,"Hello Tcp!");  
  53.  
  54.     retVal=send(sClient,buf,BUF_SIZE,0);  
  55.     if(retVal == SOCKET_ERROR)  
  56.     {  
  57.         printf("send failed!\n");  
  58.  
  59.         closesocket(sClient);  
  60.         WSACleanup();  
  61.         return -1;  
  62.     }  
  63.  
  64.     //  
  65.     closesocket(sClient);  
  66.     WSACleanup();  
  67.     return 0;  
  68. }  

函数原型:

1.

typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr_in *PSOCKADDR_IN;
typedef struct sockaddr_in FAR *LPSOCKADDR_IN;

typedef struct sockaddr SOCKADDR;
typedef struct sockaddr *PSOCKADDR;
typedef struct sockaddr FAR *LPSOCKADDR;

 

struct sockaddr_in{
  short sin_family;
  unsigned short sin_port;
  IN_ADDR sin_addr;
  char sin_zero[8];
};

short sin_family; //AF_INET,代表TCP/IP协议族

char sin_zero[8]; //填充大小和SOCKADDR结构一样(16Byetes)

 

typedef struct in_addr {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un; } in_addr;

 

struct sockaddr {
  u_short sa_family;
  char sa_data[14];
};

注:1.SOCKADDR更通用,SOCKADDR_IN针对TCP/IP协议族;2.SOCKADDR_IN弥补了SOCKADDR的地址和端口没有分开的缺陷;3.SOCKADDR_IN用于定义,SOCKADDR用于函数的参数.

2.

 

SOCKET accept(
  SOCKET s,
  struct sockaddr* addr,
  int* addrlen
);
int connect(
  SOCKET s,
  const struct sockaddr FAR* name,
  int namelen
);
Return Values

If no error occurs, accept returns a value of type SOCKET that is a descriptor for the new socket. This returned value is a handle for the socket on which the actual connection is made.

Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

 

 

int recv(
  SOCKET s,
  char* buf,
  int len,
  int flags
);
int send(
  SOCKET s,
  const char FAR* buf,
  int len,
  int flags
);

int flags //The flag that specifies the way in which the call is made. (0 | MSG_OOB | MSG_PEEK)

 

 

unsigned long inet_addr(
  const char* cp
);
int  WSACleanup (void);

 

 

 

 

int bind(
  SOCKET s,
  const struct sockaddr FAR* name,
  int namelen
);
int listen(
  SOCKET s,
  int backlog
);
int backlog //Maximum length of the queue of pending connections

 

 

*******************************************************************

typedef u_int           SOCKET;

SOCKET socket(
  int af,
  int type,
  int protocol
);

int type, //SOCK_STREAM | SOCK_DGRAM

int protocol //IPPROTO_TCP | IPPROTO_UDP
注:所谓的套接字类型(SOCKET)、协议类型(type)、句柄(HANDLE),以及套接字种类(Type)其本身都只是int 整型或者u_int,是一个32位的数字. 你给函数参数指定一个数值,系统就自动调用对应的各种类型数据(然而,实际上,内部全部是封装的,它的实现机制你一窍不通!)

你可能感兴趣的:(职场,64,comment,休闲)