用winsock和C语言进行socket通讯编程,要求服务端和客户端能互相发送和接收数据
时间: 2024-02-27 14:58:47 浏览: 79
好的,我可以为您解答。首先,您需要了解以下几个概念:
1. Socket:套接字,是网络通信的基本操作单元,负责在应用程序之间传递数据。
2. IP地址和端口号:在网络通信中,每个网络设备都有一个唯一的IP地址,而端口号则用于标识应用程序。
3. TCP和UDP协议:TCP协议提供可靠的、面向连接的通信服务,而UDP协议则提供不可靠的、无连接的通信服务。
接下来,我们来编写一个简单的客户端和服务端程序,实现数据的发送和接收。
服务端程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT 8888
int main()
{
WSADATA wsaData;
SOCKET serverSocket, clientSocket;
struct sockaddr_in serverAddr, clientAddr;
int clientAddrLen = sizeof(clientAddr);
char recvBuf[1024] = {0};
char sendBuf[1024] = {0};
int ret;
// 初始化Winsock库
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed\n");
return -1;
}
// 创建Socket
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
printf("create socket failed\n");
WSACleanup();
return -1;
}
// 绑定IP地址和端口号
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
printf("bind failed\n");
closesocket(serverSocket);
WSACleanup();
return -1;
}
// 监听端口
if (listen(serverSocket, 5) == SOCKET_ERROR) {
printf("listen failed\n");
closesocket(serverSocket);
WSACleanup();
return -1;
}
printf("server is listening on port %d\n", PORT);
// 接收客户端连接
clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
if (clientSocket == INVALID_SOCKET) {
printf("accept failed\n");
closesocket(serverSocket);
WSACleanup();
return -1;
}
// 接收客户端发送的数据
ret = recv(clientSocket, recvBuf, sizeof(recvBuf), 0);
if (ret > 0) {
printf("recv from client: %s\n", recvBuf);
}
// 发送数据给客户端
strcpy(sendBuf, "hello, client");
ret = send(clientSocket, sendBuf, strlen(sendBuf), 0);
if (ret == SOCKET_ERROR) {
printf("send failed\n");
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return -1;
}
// 关闭Socket
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return 0;
}
```
客户端程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define SERVER_IP "127.0.0.1"
#define PORT 8888
int main()
{
WSADATA wsaData;
SOCKET clientSocket;
struct sockaddr_in serverAddr;
char recvBuf[1024] = {0};
char sendBuf[1024] = {0};
int ret;
// 初始化Winsock库
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed\n");
return -1;
}
// 创建Socket
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
printf("create socket failed\n");
WSACleanup();
return -1;
}
// 连接服务器
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
printf("connect failed\n");
closesocket(clientSocket);
WSACleanup();
return -1;
}
// 发送数据给服务器
strcpy(sendBuf, "hello, server");
ret = send(clientSocket, sendBuf, strlen(sendBuf), 0);
if (ret == SOCKET_ERROR) {
printf("send failed\n");
closesocket(clientSocket);
WSACleanup();
return -1;
}
// 接收服务器发送的数据
ret = recv(clientSocket, recvBuf, sizeof(recvBuf), 0);
if (ret > 0) {
printf("recv from server: %s\n", recvBuf);
}
// 关闭Socket
closesocket(clientSocket);
WSACleanup();
return 0;
}
```
服务端程序会监听8888端口,当有客户端连接时,会接收客户端发送的数据,并发送数据给客户端。客户端程序会连接127.0.0.1的8888端口,发送数据给服务端,并接收服务端发送的数据。
注意:在Visual Studio中编译时,需要将项目属性中的“配置属性”->“C/C++”->“代码生成”->“运行库”设置为“多线程调试(/MTd)”或“多线程(/MT)”。
阅读全文