socket学习

  前几天学习了简单学习了一下socket编程,今天来回忆一下,自己在不借助资料的情况下写一下简单的C/S模式的socket。

  socket是网络编程中很重要的一个部分,它相当于数据传输的一个端口。

  客户端创建一个套接字socket的时候要指定相应的协议,本机的IP地址,本机的端口,这称为一个半相关。服务器端也是一样的,只有当两者用的协议相同,构成一个权相关,才能连接起来,进而通信。

  服务器端:

  1.初始化socket库

  2.创建socket

  3.设定地址

  4.绑定socket

  5.监听

  6.建立通信

  6.关闭socket

  1 #include<iostream>
  2 #include<winsock2.h>
  3 #pragma comment(lib,"ws2_32.lib")
  4 
  5 using namespace std;
  6 
  7 int main()
  8 {
  9     //初始化socket
 10 
 11     DWORD wVersion;
 12     WSADATA w;
 13 
 14     int err;
 15     wVersion=MAKEWORD(1,1);
 16     err=WSAStartup(wVersion,&w);
 17 
 18     if(0==err)
 19     {
 20         cout<<"socket初始化成功!\n";
 21     }
 22     else
 23     {
 24         cout<<"socket初始化失败!\n";
 25     }
 26 
 27     if (LOBYTE(wVersion)!=1||HIBYTE(wVersion)!=1)
 28     {
 29         WSACleanup();
 30         return -1;
 31     }
 32 
 33     //创建socket
 34 
 35     SOCKET sersock;
 36     sersock=socket(AF_INET,SOCK_STREAM,0);
 37 
 38     //设置地址
 39 
 40     sockaddr_in seraddr;
 41     seraddr.sin_family=AF_INET;
 42     seraddr.sin_addr.S_un.S_addr=htonl(ADDR_ANY);
 43     seraddr.sin_port=htons(6000);
 44 
 45     //绑定
 46 
 47     if(bind(sersock,(sockaddr *)&seraddr,sizeof(sockaddr))==SOCKET_ERROR)
 48     {
 49         cout<<"bind error!\n";
 50         WSACleanup();
 51         return-1;
 52     }
 53 
 54     //监听
 55 
 56     listen(sersock,5);
 57     //通信
 58 
 59     SOCKET acsock;
 60     sockaddr_in cliaddr;
 61     int len=sizeof(sockaddr);
 62 
 63     while(true)
 64     {
 65         acsock=accept(sersock,(sockaddr *)&cliaddr,&len);
 66         if(acsock==INVALID_SOCKET)
 67         {
 68             cout<<"accept failed!\n";
 69         }
 70         else
 71         {
 72             cout<<"accepted!\n";
 73         }
 74 
 75         //发送消息
 76 
 77         char buff[100]="I'm server!";
 78         int n=send(acsock,buff,sizeof(buff)+1,0);
 79         if(n==0||n==SOCKET_ERROR)
 80         {
 81             cout<<"send failed!\n";
 82         }
 83         else
 84         {
 85             cout<<"send finished!\n";
 86         }
 87         
 88         Sleep(1000);
 89 
 90         memset(buff,0,100);
 91 
 92         int m=recv(acsock,buff,sizeof(buff)+1,0);
 93         if(m==0||m==SOCKET_ERROR)
 94         {
 95             cout<<"receive failed!\n";
 96         }
 97         else
 98         {
 99             cout<<"receive finished!\n";
100             cout<<"message from "<<inet_ntoa(cliaddr.sin_addr)<<":"<<ntohs(cliaddr.sin_port)<<"  "<<buff<<endl;
101         }
102     }
103     
104     //关闭
105     if(closesocket(sersock)==SOCKET_ERROR)
106     {
107         cout<<"close error!\n";
108         WSACleanup();
109     }
110     WSACleanup();
111 
112     return 0;
113 }

  客户端:

  1.初始化socket 

  2.创建socket

  3.设定地址

  4.连接服务器

  5.通信

  6.关闭socket库

 1 #include<iostream>
 2 #include<winsock2.h>
 3 #pragma comment(lib,"ws2_32.lib")
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     //初始化socket
10 
11     DWORD wVersion;
12     WSADATA ws;
13 
14     wVersion=MAKEWORD(1,1);
15 
16     int err=WSAStartup(wVersion,&ws);
17 
18     if(err==0)
19     {
20         cout<<"初始化socket成功!\n";
21     }
22     else
23     {
24         cout<<"初始化socket失败!\n";
25     }
26 
27     if(LOBYTE(wVersion)!=1||HIBYTE(wVersion)!=1)
28     {
29         cout<<"socket版本不对!\n";
30         WSACleanup();
31     }
32 
33     //创建套接字
34 
35     SOCKET clisock;
36     clisock=socket(AF_INET,SOCK_STREAM,0);
37     //设置地址
38 
39     sockaddr_in cliaddr;
40     cliaddr.sin_family=AF_INET;
41     cliaddr.sin_addr.S_un.S_addr=inet_addr("192.168.1.110");
42     cliaddr.sin_port=htons(6000);
43 
44     //连接服务器
45 
46     if(connect(clisock,(sockaddr *)&cliaddr,sizeof(sockaddr))==SOCKET_ERROR)
47     {
48         cout<<"connect error!\n";
49         WSACleanup();
50         return -1;
51     }
52     else
53     {
54         cout<<"connected!\n";
55     }
56 
57     //通信
58 
59     char buff[100];
60     memset(buff,0,100);
61 
62     if(recv(clisock,buff,sizeof(buff)+1,0)>0)
63     {
64         cout<<"receive message from server:";
65     }
66     cout<<buff<<endl;
67 
68     memset(buff,0,100);
69     cin.getline(buff,100);
70 
71     if(send(clisock,buff,sizeof(buff)+1,0)>0)
72     {
73         cout<<"send ok!\n";
74     }
75     //关闭
76 
77     closesocket(clisock);
78     WSACleanup();
79     return 0;
80 }

  上述代码实现如下简单的功能:  

  先启动服务器端,等待客户端连接,客户端启动后,连接成功后,服务器发送消息,客户端收到消息后,输入消息,回应。

  在学习过程中,需要注意如下几点:

  1.在程序开头要加上#pragma comment(lib,"ws2_32.lib")告诉编译器有些东西要到ws2_32.lib库中去找

  2.几个函数的使用不熟练:

  inet_addr():将ip地址转化为S_addr结构类型

  inet_ntoa():将S_addr结构类型转换成ip形式的字符串

  htonl():将32位主机字节顺序转换成网络字节顺序

  htons():将16位主机字节顺序转换成网络字节顺序

  ntohl():与htonl()相反

  ntohs(): 与htons()相反

  3.程序在运行过程中,输出的端口不是6000,而是变化的,不知道为什么。。。

  4.上面的程序是基于TCP协议的,TCP协议是面向连接的,以流的形式进行传输,而UDP协议不是面向连接的,以数据报的形式进行传输。TCP协议传输,数据的正确性和可靠性比UDP高。

 

posted on 2014-07-06 10:40  再见猪小华  阅读(294)  评论(0编辑  收藏  举报

导航