只做了最基础的双向收发功能,参考了很多大佬的文章,还有很多不懂的地方,先把代码贴出来大家互相交流吧。
因为不清楚头文件具体内容,乱加了很多,看起来很冗余。
初始化操作可能有几个是多余的,懒得去掉了。
客户端:
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <sys/types.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include <process.h>
#define SERVER_PORT 6677
#define ERROR -1
int main()
{
//启动wsaData服务
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
perror("WSADATA失败");
}
//描述服务器的socket
struct sockaddr_in server_addr;
//指定服务器端的ip,本地测试:127.0.0.1
//inet_addr()函数,将点分十进制IP转换成网络字节序IP
//server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
char buffer[200];
int udpClientSocket;
//判断socket是否失败
if ((udpClientSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("socketError = %d\n", WSAGetLastError());
return ERROR;
}
printf("udpClientSocket的值为:%d\n", udpClientSocket);
//初始化服务器地址
memset(&server_addr, 0, sizeof(server_addr));
//初始化服务器端套接字并用htons和htonl将端口和地址转成网络字节序
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
//ip可以是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址,自动绑定ip
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
printf("服务器地址为:%d\n", server_addr.sin_addr.s_addr);
while (1)
{
memset(buffer, 0, sizeof(buffer));
printf("发送消息:");
scanf("%s", buffer);
printf("\n");
socklen_t len = sizeof(struct sockaddr_in);
//int udpSendto;
if (sendto(udpClientSocket, buffer, sizeof(buffer), 0, (struct sockaddr*)&server_addr, len) < 0)
{
printf("sendtoError = %d\n", WSAGetLastError());
perror("sendtoError");
return ERROR;
}
memset(buffer, 0, sizeof(buffer));
//增加退出机制
if (strcmp(buffer, "quit") == 0)
break;
printf("读取消息:");
//if (recvfrom(udpClientSocket, buffer, sizeof(buffer), 0, NULL, NULL) < 0) 此处后两个参数也可以是NULL
if (recvfrom(udpClientSocket, buffer, sizeof(buffer), 0, (struct sockaddr*)&server_addr, &len) < 0)
{
printf("recvfromError = %d\n", WSAGetLastError());
return ERROR;
}
printf("%s\n", buffer);
memset(buffer, 0, sizeof(buffer));
//增加退出机制
if (strcmp(buffer, "quit") == 0)
break;
}
close(udpClientSocket);
return 0;
}
服务器端:
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <sys/types.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include <process.h>
#define SERVER_PORT 6677
#define ERROR -1
int main()
{
int udpServerSocket;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
//启动wsaData服务
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
perror("WSADATA失败");
}
//判断socket是否失败
if ((udpServerSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("socketError = %d\n", WSAGetLastError());
return ERROR;
}
printf("udpServerSocket的值为:%d\n", udpServerSocket);
//初始化地址
memset(&server_addr, 0, sizeof(server_addr));
memset(&client_addr, 0, sizeof(client_addr));
//初始化服务器端套接字并用htons和htonl将端口和地址转成网络字节序
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
//ip可以是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//判断bind是否失败
int udpBind;
if (udpBind = bind(udpServerSocket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
printf("bindError = %d\n", WSAGetLastError());
return ERROR;
}
printf("udpBind的值为:%d\n", udpBind);
while (1)
{
printf("监听端口:%d\n", SERVER_PORT);
char buffer[200];
memset(buffer, 0, sizeof(buffer));
printf("读取消息:");
socklen_t client_addr_len = sizeof(client_addr);
if (recvfrom(udpServerSocket, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &client_addr_len) < 0)
{
printf("recvfromError = %d\n", WSAGetLastError());
return ERROR;
}
printf("%s\n", buffer);
//增加退出机制
if (strcmp(buffer, "quit") == 0)
break;
memset(buffer, 0, sizeof(buffer));
printf("发送消息:");
scanf("%s", buffer);
printf("\n");
int udpSendto;
if (udpSendto = (sendto(udpServerSocket, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, client_addr_len)) < 0)
{
printf("sendtoError = %d\n", WSAGetLastError());
return ERROR;
}
memset(buffer, 0, sizeof(buffer));
//增加退出机制
if (strcmp(buffer, "quit") == 0)
break;
}
close(udpServerSocket);
return 0;
}