C语言下hello/hi 网络聊天程序编程及WinSocket分析

一、hello/hi网络程序编程

1、服务端

 1 sever.c
 2 #include<stdio.h>
 3 #include<Winsock2.h>
 4 #include<time.h>
 5 #include<string.h>
 6 #pragma warning(disable:4996)
 7 #pragma comment(lib,"ws2_32.lib")
 8 
 9 #define USER_ERROR -1
10 
11 int main()
12 {
13     char recvData[200];
14     char sendData[200];
15     int ret;
16     WSADATA wsaData;
17     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
18     {
19         printf("Failed to load Winsock.\n");
20         return USER_ERROR;
21     }
22 
23     SOCKET socket_of_server;
24     SOCKET socket_of_client;
25     socket_of_server = socket(AF_INET, SOCK_STREAM, 0);
26     if (socket_of_server == INVALID_SOCKET)
27     {
28         printf("socket() Failed:%d\n", WSAGetLastError());
29         return USER_ERROR;
30     }
31 
32     struct sockaddr_in s_sin;
33     s_sin.sin_family = AF_INET;
34     s_sin.sin_port = htons(6666);
35     s_sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
36     if (bind(socket_of_server, (LPSOCKADDR)&s_sin, sizeof(s_sin)) == SOCKET_ERROR)
37     {
38         printf("blind() Failed:%d\n", WSAGetLastError());
39         return USER_ERROR;
40     }
41     if (listen(socket_of_server, 5) == SOCKET_ERROR)
42     {
43         printf("listen() Failed:%d\n", WSAGetLastError());
44         return USER_ERROR;
45     }
46     struct sockaddr_in c_sin;
47     int c_sin_len = sizeof(c_sin);
48     while (1)
49     {
50         printf("waiting for connect\n");
51         socket_of_client = accept(socket_of_server, (SOCKADDR*)&c_sin, &c_sin_len);
52         if (socket_of_client == INVALID_SOCKET)
53             printf("accept() Failed:%d\n", WSAGetLastError());
54         else
55         {
56             printf("接收到一个连接:%s\r\n", inet_ntoa(c_sin.sin_addr));
57             while (1)
58             {
59                 printf("读取消息:");
60                 recvData[0] = '\0';
61                 ret = recv(socket_of_client, recvData, 200, 0);
62                 if (ret < 0)
63                 {
64                     printf("something wrong\n");
65                     continue;
66                 }
67                 recvData[ret] = '\0';
68                 if (strcmp(recvData, "quit") == 0)
69                     break;
70                 printf("%s\n", recvData);
71                 printf("发送消息:");
72                 scanf("%s", sendData);
73                 printf("\n");
74                 send(socket_of_client, sendData, strlen(sendData), 0);
75                 if (strcmp("quit", sendData) == 0)
76                     break;
77             }
78         }
79 
80     }
81 
82     closesocket(socket_of_server);
83     WSACleanup();
84     return 0;
85 }

2、客户端

 1 client.c
 2 #include <winsock2.h>
 3 #include <time.h>
 4 #include <stdio.h>
 5 #include <string.h>
 6 #include <direct.h> 
 7 #pragma comment(lib,"ws2_32.lib")
 8 #pragma warning(disable:4996)
 9 
10 #define USER_ERROR -1
11 
12 int main()
13 {
14     char recvData[200];
15     char sendData[200];
16     int ret;
17 
18 
19     WSADATA wsaData;
20     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
21     {
22         printf("Failed to load Winsock.\n");
23         return USER_ERROR;
24     }
25 
26     SOCKET socket_client = socket(AF_INET, SOCK_STREAM, 0);
27     if (socket_client == INVALID_SOCKET)
28     {
29         printf(" Failed socket() \n");
30         return 0;
31     }
32 
33     struct sockaddr_in server_in;
34     server_in.sin_family = AF_INET;
35     server_in.sin_port = htons(6666);
36     server_in.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
37 
38     if (connect(socket_client, (struct sockaddr*) & server_in, sizeof(server_in)) == -1)
39     {
40         printf(" Failed connect() \n");
41         return 0;
42     }
43     else
44     {
45         printf("connect %s.%d\n", inet_ntoa(server_in.sin_addr), server_in.sin_port);
46         while (1)
47         {
48             printf("发送消息:");
49             scanf("%s", sendData);
50             printf("\n");
51             send(socket_client, sendData, strlen(sendData), 0);
52             if (strcmp(sendData, "quit") == 0)
53                 break;
54             printf("读取消息:");
55             recvData[0] = '\0';
56             ret = recv(socket_client, recvData, 200, 0);
57             recvData[ret] = '\0';
58             printf("%s\n", recvData);
59         }
60 
61     }
62     closesocket(socket_client);
63     WSACleanup();
64     return 0;
65 } 

3、示例图

二、WinSocket分析

1、WSAStartup()——初始化Socket

   定义函数为int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData ),为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。使用Socket的程序在使用Socket之前必须调用WSAStartup函数。

2、socket()——建立一个Socket通信

  定义函数为int socket(int domain,int type,int protocol),socket()用来建立一个新的socket,也就是向系统注册,通知系统建立一通信端口,参数domain 指定使用何种的地址类型,完整的定义在/usr/include/bits/socket.h 内。

3、listen()——等待连接

  定义函数为int listen(int s,int backlog),listen()用来等待参数s 的socket连线。Listen()并未开始接收连线,只是设置socket为listen模式,真正接收client端连线的是accept()。通常listen()会在socket(),bind()之后调用,接着才调用accept()。

4、connect()——建立Socket连接

  定义函数为int connect (int sockfd,struct sockaddr * serv_addr,int addrlen),connect()用来将参数sockfd 的socket 连至参数serv_addr 指定的网络地址。结构sockaddr请参考bind()。参数addrlen为sockaddr的结构长度。

5、bind()——对Socket定位

  定义函数为int bind(int sockfd,struct sockaddr * my_addr,int addrlen),bind()用来设置给参数sockfd的socket一个名称。此名称由参数my_addr指向一sockaddr结构,对于不同的socket domain定义了一个通用的数据结构。

6、accept()——接受Socket连线

  定义函数为int accept(int s,struct sockaddr * addr,int * addrlen),

accept()用来接受参数s的socket连线。参数s的socket必需先经bind()、listen()函数处理过,当有连线进来时accept()会返回一个新的socket处理代码,往后的数据传送与读取就是经由新的socket处理,而原来参数s的socket能继续使用accept()来接受新的连线要求。连线成功时,参数addr所指的结构会被系统填入远程主机的地址数据。

7、recv()——经Socket接受数据

  定义函数为int recv(int s,void *buf, int len, unsigned int flags),recv()用来接收远端主机经指定的socket传来的数据,并把数据存到由参数buf 指向的内存空间,参数len为可接收数据的最大长度。

8、send()——经Socket发送数据

  定义函数为int send(int s,const void * msg,int len,unsigned int falgs),send()用来将数据由指定的socket 传给对方主机。参数s为已建立好连接的socket。参数msg指向欲连线的数据内容,参数len则为数据长度。

猜你喜欢

转载自www.cnblogs.com/yusi007/p/12005066.html