server.cpp
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
/*
UDP Server网络编程的基本步骤
创建socket, 指定udp协议
将socket与地址和端口绑定
使用 recvfrom/sendto 接收/发送数据
使用close关闭连接
*/
int main(int argc, char * *argv)
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9876);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
char buff_recv[512] = {0};
char buff_send[512] = "world";
struct sockaddr_in clientAddr;
int n;
int len = sizeof(clientAddr);
int sock;
printf("Welcome! This is a UDP server.\n");
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("socket error.\n");
exit(1);
}
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
printf("bind error.\n");
exit(1);
}
while (1)
{
n = recvfrom(sock, buff_recv, 511, 0, (struct sockaddr *) &clientAddr,(socklen_t*) &len);
if (n > 0)
{
buff_recv[n] = 0;
printf("recv data from client:%s %u says: %s\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port), buff_recv);
n = sendto(sock, buff_send, n, 0, (struct sockaddr *) &clientAddr, sizeof(clientAddr));
if (n < 0)
{
printf("sendto error.\n");
break;
}else {
printf("send data len %d \n",n);
}
}
}
return 0;
}
//g++ udp_server.c -o userver
client.cpp
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char * *argv)
{
struct sockaddr_in addr;
int sock;
addr.sin_family = AF_INET;
addr.sin_port = htons(9876);
addr.sin_addr.s_addr = inet_addr("192.168.0.126"); //127.0.0.1
char buff_send[512] = "Hello";
char buff_recv[512] = {0};
int len = sizeof(addr);
int n = 0;
printf("This is a UDP client\n");
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("socket error.\n");
exit(1);
}
if (addr.sin_addr.s_addr == INADDR_NONE)
{
printf("Incorrect ip address!");
close(sock);
exit(1);
}
n = sendto(sock, buff_send, strlen(buff_send), 0, (struct sockaddr *) &addr, sizeof(addr));
if (n < 0)
{
printf("sendto error.\n");
close(sock);
}
n = recvfrom(sock, buff_recv, 512, 0, (struct sockaddr *) &addr,(socklen_t*)&len);
if (n > 0)
{
buff_recv[n] = 0;
printf("received from sever:");
puts(buff_recv);
}
else if (n == 0)
printf("server closed.\n");
else if (n == -1)
printf("recvfrom error.\n");
pause();
close(sock);
return 0;
}
//g++ udp_client.c -o uclient
window platform
udpclient:
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define BUF_SIZE 1024
#define PORT_ 9411
int main(void)
{
WSADATA wsd;
int iRet = 0;
// 初始化套接字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {
iRet = WSAGetLastError();
printf("WSAStartup failed !\n");
return -1;
}
char strSend[BUF_SIZE] = "test udp send", strRecv[BUF_SIZE] = { 0 };
SOCKADDR_IN servAddr;
SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
// 设置服务器地址
servAddr.sin_family = AF_INET;
//servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.104");
servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.106");
servAddr.sin_port = htons(PORT_);
// 向服务器发送数据
int nServAddLen = sizeof(servAddr);
iRet = sendto(sockClient, strSend, BUF_SIZE, 0, (sockaddr*)&servAddr, nServAddLen);
if (iRet == SOCKET_ERROR) {
printf("sendto() failed:%d\n", WSAGetLastError());
closesocket(sockClient);
WSACleanup();
return -1;
}
iRet = recvfrom(sockClient, strRecv, BUF_SIZE, 0, (sockaddr*)&servAddr, &nServAddLen);
if (SOCKET_ERROR == iRet)
{
printf("recvfrom failed:%d\n", WSAGetLastError());
closesocket(sockClient);
WSACleanup();
return -1;
}
printf("Recv From Server:%s\n", strRecv);
closesocket(sockClient);
WSACleanup();
return 0;
}
udpserver
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define BUF_SIZE 1024
#define PORT_ 9411
int main(void)
{
WSADATA wsd;
int iRet = 0;
// 初始化套接字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {
printf("WSAStartup failed:%d!\n", WSAGetLastError());
return -1;
}
SOCKET socketSrv = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
SOCKADDR_IN addrSrv;
SOCKADDR_IN addrClient;
char strRecv[BUF_SIZE] = { 0 }, strSend[BUF_SIZE] = "udp server send";
int len = sizeof(SOCKADDR);
// 设置服务器地址
ZeroMemory(strRecv, BUF_SIZE);
//addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.106");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(PORT_);
// 绑定套接字
iRet = bind(socketSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
if (SOCKET_ERROR == iRet)
{
printf("bind failed%d!\n", WSAGetLastError());
closesocket(socketSrv);
WSACleanup();
}
// 从客户端接收数据
printf("udp server start...\n");
while (TRUE)
{
iRet = recvfrom(socketSrv, strRecv, BUF_SIZE, 0, (SOCKADDR*)&addrClient, &len);
if (SOCKET_ERROR == iRet) {
printf("recvfrom failed !\n");
closesocket(socketSrv);
WSACleanup();
return -1;
}
printf("Recv From Client:%s\n", strRecv);
// 向客户端发送数据
sendto(socketSrv, strSend, sizeof(strSend), 0, (SOCKADDR*)&addrClient, len);
}
closesocket(socketSrv);
WSACleanup();
return 0;
}
Under windows, pay attention to socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); If the third parameter is IPPROTO_IP, otherwise recvfrom will always return -1
#include <iostream>
#include <winsock2.h>
#include<string.h>
#include<sstream>
#include <stdlib.h>
#include <thread>
#pragma comment(lib,"ws2_32.lib")
int main() {
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
SOCKET Client;
Client = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); //IPPROTO_UDP
SOCKADDR_IN sockAddrIn;
memset(&sockAddrIn, 0, sizeof(sockAddrIn));
sockAddrIn.sin_family = AF_INET;
sockAddrIn.sin_port = htons(9876 );
sockAddrIn.sin_addr.s_addr = inet_addr("192.168.0.126"); // 182.254.212.98 223.104.212.61 56039 92.168.0.126
//设置socket的选项
//int time_out = 2000;
//if (setsockopt(Client, SOL_SOCKET, SO_RCVTIMEO, (char*)&time_out, sizeof(time_out)) != 0) {
// return -1;
//}
bool isconn=false;
while (true) {
char buf[200]="i am client";
char buff_recv[512] = { 0 };
int len= sizeof(sockAddrIn);
scanf("%s", buf);
int recvRet;
int sendRet;
if (!isconn)
{
sendRet = sendto(Client, buf, strlen(buf)+1, 0, (sockaddr*)&sockAddrIn, sizeof(sockAddrIn));
if (sendRet == -1) {
std::cout << WSAGetLastError() << std::endl;
std::cout << "send failed" << std::endl;
break;
}
else {
std::cout << "send success" << std::endl;
}
recvRet = recvfrom(Client, buff_recv, 511, 0, (sockaddr*)&sockAddrIn, &len);
std::cout << recvRet << std::endl;
std::cout << "serverdata:" << buff_recv << std::endl;
char *strtemp=strstr(buff_recv, ":");
if (strtemp != NULL)
{
//std::cout << strtemp << std::endl;
int mid= strlen(buff_recv) - strlen(strtemp);
buff_recv[mid] = 0;
std::cout << buff_recv << std::endl;
sockAddrIn.sin_port = htons(atoi(strtemp + 1));
sockAddrIn.sin_addr.s_addr = inet_addr(buff_recv);
std::cout << "port:" << atoi(strtemp+1)<<"\n ip:"<< buff_recv << std::endl;
sendto(Client, buf, strlen(buf) + 1, 0, (sockaddr*)&sockAddrIn, sizeof(sockAddrIn)); //p2p 连接
isconn = true;
}
}
std::this_thread::sleep_for ( std::chrono::seconds(1));
//开始通信
sendto(Client, buf, strlen(buf) + 1, 0, (sockaddr*)&sockAddrIn, sizeof(sockAddrIn));
recvRet = recvfrom(Client, buff_recv, 511, 0, (sockaddr*)&sockAddrIn, &len);
std::cout << recvRet << std::endl;
if (recvRet == -1) {
continue;
}
else {
std::cout <<"serverdata:"<< buff_recv << std::endl;
}
}
return 0;
}