一个关于跨平台UDP通信的问题
因为一个嵌入式项目的需要,现在在做上位机PC机(Windows系统)与下位机ARM处理器(linux系统)的UDP通信。我现在已经把windows系统上的UDP发送接收程序调试好了,发送的数据可以接收。然后我在虚拟机(装的是ubuntu系统)上写了个接收程序,用Windows上的发送程序发送数据,却总是接收不到。
我感觉发送程序总是卡在sendto函数那里,因为我Dubug的时候输入要发送的数据回车之后Debug就一直卡在那里了,但是我在Windows上跑接收程序的时候,在发送端输入数据回车之后接收程序是回返回一个接收成功的信号的。
我不太清楚Windows与linux通信有没有什么数据格式要转换之类要注意的点存在,我只是很简单的调用socket函数来进行发送与接收。下面是我在Windows下的发送程序UDPClient和在linux下的接收程序UDPServer,很简单的socket调用没有什么别的复杂的东西,查了几天了不知道问题出在什么地方,有没有高手可以帮一下忙,谢谢了
(PS:网络ping过是通的没问题)
在WINDOWS上的UDP发送端程序:
/*
UDP Client
*/
#include <WINSOCK2.H>
#include <stdio.h>
#pragma comment(lib, "ws2_32")
#define SERVER_PORT 9001
#define MAXBUFLEN 1024
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Usage: %s <Server_IP>\n", argv[0]);
//return 1;
}
const char* const serverip = argv[1];
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(1, 1);
if(WSAStartup(wVersionRequested, &wsaData) != 0)
{
return -1;
}
if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
return -1;
}
SOCKET sock_client;
if((sock_client = socket(AF_INET, SOCK_DGRAM, 0)) == -1)// 创建客户端socket
{
perror("socket");
WSACleanup();
return -1;
}
SOCKADDR_IN addr_server;// 定义服务端地址
addr_server.sin_family = AF_INET;
addr_server.sin_addr.S_un.S_addr = inet_addr(serverip);// 设置服务端IP地址
addr_server.sin_port = htons(SERVER_PORT);
char buf[MAXBUFLEN] = {0};
int addr_len = sizeof(SOCKADDR);
int err;
BOOL bBroadcast = TRUE;
setsockopt(sock_client, SOL_SOCKET, SO_BROADCAST/* broadcast data */, (char*)&bBroadcast, sizeof(BOOL));
while(1)
{
printf("Client: ");
gets(buf);// 输入要发送的信息
if(sendto(sock_client, buf, strlen(buf)+1, 0, (SOCKADDR*)&addr_server, addr_len) == -1)
{
err = WSAGetLastError();
printf("error:%d\n",err);
perror("sendto");
//break;
}
if(recvfrom(sock_client, buf, MAXBUFLEN, 0, (SOCKADDR*)&addr_server, &addr_len) == -1)
{
perror("recvfrom");
//break;
}
printf("Server: %s\n", buf);
if(stricmp(buf, "Bye") == 0)// 接收到"Bye"将退出程序
//break;
;
}
closesocket(sock_client);
WSACleanup();
return 0;
}
Linux上的UDP接收程序:
/*
功能:UDP Server[Linux]
*/
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 6000
#define MAXBUFLEN 1024
int main(int argc, char *argv[])
{
const char* const serverip = argv[1];
int sock_server;
struct sockaddr_in server_addr, client_addr;
if((sock_server = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
return -1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&server_addr.sin_zero, 8);
if(bind(sock_server, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
close(sock_server);
return -1;
}
printf("Server started, listening at port %d\n\n", SERVER_PORT);
int nbytes = 0;
char buf[MAXBUFLEN] = {0};
int addr_len = sizeof(struct sockaddr);
while(1)
{
if((nbytes = recvfrom(sock_server, buf, MAXBUFLEN, 0, (struct sockaddr*)&client_addr, &addr_len)) == -1)
{
perror("recvfrom");
break;
}
printf("Client: %s\n", buf);
if(strcasecmp(buf, "quit") == 0)
strcpy(buf, "Bye");
else
strcpy(buf, "OK");
printf("Server: %s\n", buf);
if((nbytes = sendto(sock_server, buf, strlen(buf)+1, 0, (struct sockaddr*)&client_addr, addr_len)) == -1)
{
perror("sendto");
break;
}
if(strcasecmp(buf, "Bye") == 0)// 当服务端返回"Bye"后立刻退出程序
break;
}
close(sock_server);
return 0;
}
[解决办法]
修改了你程序,测试没什么错误!
windows客户端:
// myTest.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"/*UDP Client*/#include <WINSOCK2.H>#include <stdio.h>#pragma comment(lib, "ws2_32")#define SERVER_PORT 9001#define MAXBUFLEN 1024int main(int argc, char *argv[]){ if(argc < 2) { printf("Usage: %s <Server_IP>\n", argv[0]); // return 1; } const char* const serverip = "10.3.18.105"; //修改的地方。需要绑定服务器IP WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); if(WSAStartup(wVersionRequested, &wsaData) != 0) { return -1; } if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return -1; } SOCKET sock_client; if((sock_client = socket(AF_INET, SOCK_DGRAM, 0)) == -1) // 创建客户端socket { perror("socket"); WSACleanup(); return -1; } SOCKADDR_IN addr_server; // 定义服务端地址 addr_server.sin_family = AF_INET; addr_server.sin_addr.S_un.S_addr = inet_addr(serverip); // 设置服务端IP地址 addr_server.sin_port = htons(SERVER_PORT); char buf[MAXBUFLEN] = {0}; int addr_len = sizeof(SOCKADDR); int err; BOOL bBroadcast = TRUE; setsockopt(sock_client, SOL_SOCKET, SO_BROADCAST/* broadcast data */, (char*)&bBroadcast, sizeof(BOOL)); while(1) { printf("Client: "); gets(buf); // 输入要发送的信息 if(sendto(sock_client, buf, strlen(buf)+1, 0, (SOCKADDR*)&addr_server, addr_len) == -1) { err = WSAGetLastError(); printf("error:%d\n",err); perror("sendto"); // break; } if(recvfrom(sock_client, buf, MAXBUFLEN, 0, (SOCKADDR*)&addr_server, &addr_len) == -1) { perror("recvfrom"); // break; } printf("Server: %s\n", buf); if(stricmp(buf, "Bye") == 0) // 接收到"Bye"将退出程序 // break; ; } closesocket(sock_client); WSACleanup(); return 0;}