socket入门
对于一个初学者来说,写代码是痛苦的,写不会的代码更痛苦,然后对于网上残次不齐的源码,blog不懂怎么实现痛上加痛。
本文仅仅站在入门基础上写SOCKET代码,并且代码非原创。
1.怎么建工程
VS编译器:文件->新建->项目;
大概是这样。
然后是名称随便,然后下一步,完成。
大概是这样。
注意那个 #include “stdafx.h"
基本上 你用win32控制台写代码都需要这个头文件。
代码引用这个博客:http://blog.csdn.net/orange_xxx/article/details/7276868(版权所有)
然后 这个代码复制这段代码:
1 // Server.cpp : Defines the entry point for the console application.
2 //
3 #include "stdafx.h"
4 #include "winsock2.h"
5 #pragma comment(lib, "ws2_32.lib")//这段代码每个socket代码要自己学,或者手动加入库
6 #include <iostream>
7 #include<string.h>
8 #include<stdlib.h>
9
10 using namespace std;
11 int main(int argc, char* argv[])
12 {
13 const int BUF_SIZE = 64;
14 WSADATA wsd; //WSADATA变量
15 SOCKET sServer; //服务器套接字
16 SOCKET sClient; //客户端套接字
17 SOCKADDR_IN addrServ;; //服务器地址
18 char buf[BUF_SIZE]; //接收数据缓冲区
19 char sendBuf[BUF_SIZE];//返回给客户端得数据
20 int retVal; //返回值
21 //初始化套结字动态库
22 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
23 {
24 cout << "WSAStartup failed!" << endl;
25 return 1;
26 }
27
28 //创建套接字
29 sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
30 if (INVALID_SOCKET == sServer)
31 {
32 cout << "socket failed!" << endl;
33 WSACleanup();//释放套接字资源;
34 return -1;
35 }
36
37 //服务器套接字地址
38 addrServ.sin_family = AF_INET;
39 addrServ.sin_port = htons(4999);
40 addrServ.sin_addr.s_addr = INADDR_ANY;
41 //绑定套接字
42 retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
43 if (SOCKET_ERROR == retVal)
44 {
45 cout << "bind failed!" << endl;
46 closesocket(sServer); //关闭套接字
47 WSACleanup(); //释放套接字资源;
48 return -1;
49 }
50
51 //开始监听
52 retVal = listen(sServer, 1);
53 if (SOCKET_ERROR == retVal)
54 {
55 cout << "listen failed!" << endl;
56 closesocket(sServer); //关闭套接字
57 WSACleanup(); //释放套接字资源;
58 return -1;
59 }
60
61 //接受客户端请求
62 sockaddr_in addrClient;
63 int addrClientlen = sizeof(addrClient);
64 sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientlen);
65 if (INVALID_SOCKET == sClient)
66 {
67 cout << "accept failed!" << endl;
68 closesocket(sServer); //关闭套接字
69 WSACleanup(); //释放套接字资源;
70 return -1;
71 }
72
73 while (true)
74 {
75 //接收客户端数据
76 ZeroMemory(buf, BUF_SIZE);
77 retVal = recv(sClient, buf, BUF_SIZE, 0);
78 if (SOCKET_ERROR == retVal)
79 {
80 cout << "recv failed!" << endl;
81 closesocket(sServer); //关闭套接字
82 closesocket(sClient); //关闭套接字
83 WSACleanup(); //释放套接字资源;
84 return -1;
85 }
86 if (buf[0] == '0')
87 break;
88 cout << "客户端发送的数据: " << buf << endl;
89
90 cout << "向客户端发送数据: ";
91 gets_s(buf);
92
93 send(sClient, sendBuf, strlen(sendBuf), 0);
94 }
95
96 //退出
97 closesocket(sServer); //关闭套接字
98 closesocket(sClient); //关闭套接字
99 WSACleanup(); //释放套接字资源;
100
101 return 0;
102 }
2 //
3 #include "stdafx.h"
4 #include "winsock2.h"
5 #pragma comment(lib, "ws2_32.lib")//这段代码每个socket代码要自己学,或者手动加入库
6 #include <iostream>
7 #include<string.h>
8 #include<stdlib.h>
9
10 using namespace std;
11 int main(int argc, char* argv[])
12 {
13 const int BUF_SIZE = 64;
14 WSADATA wsd; //WSADATA变量
15 SOCKET sServer; //服务器套接字
16 SOCKET sClient; //客户端套接字
17 SOCKADDR_IN addrServ;; //服务器地址
18 char buf[BUF_SIZE]; //接收数据缓冲区
19 char sendBuf[BUF_SIZE];//返回给客户端得数据
20 int retVal; //返回值
21 //初始化套结字动态库
22 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
23 {
24 cout << "WSAStartup failed!" << endl;
25 return 1;
26 }
27
28 //创建套接字
29 sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
30 if (INVALID_SOCKET == sServer)
31 {
32 cout << "socket failed!" << endl;
33 WSACleanup();//释放套接字资源;
34 return -1;
35 }
36
37 //服务器套接字地址
38 addrServ.sin_family = AF_INET;
39 addrServ.sin_port = htons(4999);
40 addrServ.sin_addr.s_addr = INADDR_ANY;
41 //绑定套接字
42 retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
43 if (SOCKET_ERROR == retVal)
44 {
45 cout << "bind failed!" << endl;
46 closesocket(sServer); //关闭套接字
47 WSACleanup(); //释放套接字资源;
48 return -1;
49 }
50
51 //开始监听
52 retVal = listen(sServer, 1);
53 if (SOCKET_ERROR == retVal)
54 {
55 cout << "listen failed!" << endl;
56 closesocket(sServer); //关闭套接字
57 WSACleanup(); //释放套接字资源;
58 return -1;
59 }
60
61 //接受客户端请求
62 sockaddr_in addrClient;
63 int addrClientlen = sizeof(addrClient);
64 sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientlen);
65 if (INVALID_SOCKET == sClient)
66 {
67 cout << "accept failed!" << endl;
68 closesocket(sServer); //关闭套接字
69 WSACleanup(); //释放套接字资源;
70 return -1;
71 }
72
73 while (true)
74 {
75 //接收客户端数据
76 ZeroMemory(buf, BUF_SIZE);
77 retVal = recv(sClient, buf, BUF_SIZE, 0);
78 if (SOCKET_ERROR == retVal)
79 {
80 cout << "recv failed!" << endl;
81 closesocket(sServer); //关闭套接字
82 closesocket(sClient); //关闭套接字
83 WSACleanup(); //释放套接字资源;
84 return -1;
85 }
86 if (buf[0] == '0')
87 break;
88 cout << "客户端发送的数据: " << buf << endl;
89
90 cout << "向客户端发送数据: ";
91 gets_s(buf);
92
93 send(sClient, sendBuf, strlen(sendBuf), 0);
94 }
95
96 //退出
97 closesocket(sServer); //关闭套接字
98 closesocket(sClient); //关闭套接字
99 WSACleanup(); //释放套接字资源;
100
101 return 0;
102 }
对于客户端也是类似建工程:
1 #include "stdafx.h"
2 #include "winsock2.h"
3 #include <iostream>
4 #pragma comment(lib, "ws2_32.lib")
5
6 using namespace std;
7 BOOL RecvLine(SOCKET s, char* buf); //读取一行数据
8
9 int main(int argc, char* argv[])
10 {
11 const int BUF_SIZE = 64;
12
13 WSADATA wsd; //WSADATA变量
14 SOCKET sHost; //服务器套接字
15 SOCKADDR_IN servAddr; //服务器地址
16 char buf[BUF_SIZE]; //接收数据缓冲区
17 char bufRecv[BUF_SIZE];
18 int retVal; //返回值
19 //初始化套结字动态库
20 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
21 {
22 cout << "WSAStartup failed!" << endl;
23 return -1;
24 }
25 //创建套接字
26 sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
27 if (INVALID_SOCKET == sHost)
28 {
29 cout << "socket failed!" << endl;
30 WSACleanup();//释放套接字资源
31 return -1;
32 }
33
34 //设置服务器地址
35 servAddr.sin_family = AF_INET;
36 servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
37 servAddr.sin_port = htons((short)4999);
38 int nServAddlen = sizeof(servAddr);
39
40 //连接服务器
41 retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
42 if (SOCKET_ERROR == retVal)
43 {
44 cout << "connect failed!" << endl;
45 closesocket(sHost); //关闭套接字
46 WSACleanup(); //释放套接字资源
47 return -1;
48 }
49 while (true)
50 {
51 //向服务器发送数据
52 ZeroMemory(buf, BUF_SIZE);
53 cout << " 向服务器发送数据: ";
54 cin >> buf;
55 retVal = send(sHost, buf, strlen(buf), 0);
56 if (SOCKET_ERROR == retVal)
57 {
58 cout << "send failed!" << endl;
59 closesocket(sHost); //关闭套接字
60 WSACleanup(); //释放套接字资源
61 return -1;
62 }
63 //RecvLine(sHost, bufRecv);
64 ZeroMemory(bufRecv, BUF_SIZE);
65 recv(sHost, bufRecv, BUF_SIZE, 0); // 接收服务器端的数据, 只接收5个字符
66 cout << endl << "从服务器接收数据:" << bufRecv;
67 cout << endl;
68 }
69 //退出
70 closesocket(sHost); //关闭套接字
71 WSACleanup(); //释放套接字资源
72 return 0;
73 }
2 #include "winsock2.h"
3 #include <iostream>
4 #pragma comment(lib, "ws2_32.lib")
5
6 using namespace std;
7 BOOL RecvLine(SOCKET s, char* buf); //读取一行数据
8
9 int main(int argc, char* argv[])
10 {
11 const int BUF_SIZE = 64;
12
13 WSADATA wsd; //WSADATA变量
14 SOCKET sHost; //服务器套接字
15 SOCKADDR_IN servAddr; //服务器地址
16 char buf[BUF_SIZE]; //接收数据缓冲区
17 char bufRecv[BUF_SIZE];
18 int retVal; //返回值
19 //初始化套结字动态库
20 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
21 {
22 cout << "WSAStartup failed!" << endl;
23 return -1;
24 }
25 //创建套接字
26 sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
27 if (INVALID_SOCKET == sHost)
28 {
29 cout << "socket failed!" << endl;
30 WSACleanup();//释放套接字资源
31 return -1;
32 }
33
34 //设置服务器地址
35 servAddr.sin_family = AF_INET;
36 servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
37 servAddr.sin_port = htons((short)4999);
38 int nServAddlen = sizeof(servAddr);
39
40 //连接服务器
41 retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
42 if (SOCKET_ERROR == retVal)
43 {
44 cout << "connect failed!" << endl;
45 closesocket(sHost); //关闭套接字
46 WSACleanup(); //释放套接字资源
47 return -1;
48 }
49 while (true)
50 {
51 //向服务器发送数据
52 ZeroMemory(buf, BUF_SIZE);
53 cout << " 向服务器发送数据: ";
54 cin >> buf;
55 retVal = send(sHost, buf, strlen(buf), 0);
56 if (SOCKET_ERROR == retVal)
57 {
58 cout << "send failed!" << endl;
59 closesocket(sHost); //关闭套接字
60 WSACleanup(); //释放套接字资源
61 return -1;
62 }
63 //RecvLine(sHost, bufRecv);
64 ZeroMemory(bufRecv, BUF_SIZE);
65 recv(sHost, bufRecv, BUF_SIZE, 0); // 接收服务器端的数据, 只接收5个字符
66 cout << endl << "从服务器接收数据:" << bufRecv;
67 cout << endl;
68 }
69 //退出
70 closesocket(sHost); //关闭套接字
71 WSACleanup(); //释放套接字资源
72 return 0;
73 }
实现的是这个效果,当然这段代码有问题,而且这是最基本的实现(建立连接后,一个发送,一个接受,交替进行。
关于 最终版本,多进程socket的话之后我再整理到一个文件,发送源码,建工程类似
随性Code