socket udp

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "winsock2.h"




typedef struct tagSOCKET_SERVER_INFO_S
{
int port;
char ip[32];
}SOCKET_SERVER_INFO_S;


int clientSendThread(void* pv)
{
SOCKET sendSocket;
sockaddr_in serverAddr;
SOCKET_SERVER_INFO_S *serverInfo = (SOCKET_SERVER_INFO_S *)pv;
int ret = 0;


sendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(serverInfo->port);
serverAddr.sin_addr.s_addr = inet_addr(serverInfo->ip);


while(TRUE)
{
char buf[64];


_snprintf(buf, sizeof(buf), "client(%d)'s message, last ret(%d)", GetCurrentThreadId(), ret);


 ret = sendto(sendSocket, buf, sizeof(buf), 0, (SOCKADDR *) &serverAddr, sizeof(serverAddr));
srand( (unsigned)GetTickCount());
Sleep((rand()%2 == 0)? 3000:1000);
}


closesocket(sendSocket);
return 0;
}


void runClient(SOCKET_SERVER_INFO_S *serverInfo)
{
HANDLE clientThreadHandle1 = NULL;
HANDLE clientThreadHandle2 = NULL;


clientThreadHandle1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)clientSendThread, serverInfo, 0, NULL);
clientThreadHandle2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)clientSendThread, serverInfo, CREATE_SUSPENDED, NULL);


Sleep(500);
ResumeThread (clientThreadHandle2);


CloseHandle(clientThreadHandle1);
CloseHandle(clientThreadHandle2);
}


int serverRecvThread(void* pv)
{
SOCKET recvSocket;
sockaddr_in serverAddr;
SOCKET_SERVER_INFO_S *serverInfo = (SOCKET_SERVER_INFO_S *)pv;
int serverAddrSize = sizeof(serverAddr);


recvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(serverInfo->port);
serverAddr.sin_addr.s_addr  = htonl(INADDR_ANY);


  bind(recvSocket, (SOCKADDR *) &serverAddr, sizeof(serverAddr));


while(TRUE)
{
char buf[64] = {0};


int ret = 0;
 ret = recvfrom(recvSocket, buf, sizeof(buf), 0, (SOCKADDR *) &serverAddr, &serverAddrSize);


 printf("recv: [%s] ret(%d)\n", buf, ret);


}


closesocket(recvSocket);


return 0;
}


void runServer(SOCKET_SERVER_INFO_S *serverInfo)
{
HANDLE serverThreadHandle = NULL;


serverThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)serverRecvThread, serverInfo, 0, NULL);


CloseHandle(serverThreadHandle);
}


void initApp(SOCKET_SERVER_INFO_S *serverInfo)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);


memset(serverInfo, 0, sizeof(SOCKET_SERVER_INFO_S));


serverInfo->port = 9527;
strncpy(serverInfo->ip, "127.127.0.1", sizeof(serverInfo->ip));


printf("init app, ip(%s) port(%d)\n", serverInfo->ip, serverInfo->port);
}


void destroyApp()
{
printf("bye\n");
WSACleanup();
}


int main(int a, char** b)
{
static SOCKET_SERVER_INFO_S serverInfo;


initApp(&serverInfo);




runServer(&serverInfo);
runClient(&serverInfo);


getchar();


destroyApp();


return 0;
}

### Socket UDP 编程概述 Socket 是应用程序与网络通信之间的桥梁,支持多种协议栈。对于UDP(用户数据报协议),其特点是非连接、无可靠性的传输方式,在某些场景下具有更高的效率。 在创建基于UDPSocket时,需指定`AF_INET`和`SOCK_DGRAM`参数以表明使用IPv4地址族以及采用UDP作为传输层协议[^1]。 为了更好地管理和操作已建立的套接字,通常会调用`bind()`函数将本地地址绑定到该套接字上,这一步骤并非强制但在实际应用中较为常见[^3]。 当涉及到具体的数据交换过程时,服务端可通过`recvfrom()`接收来自任意客户端的信息并获得对方地址详情;而客户端则利用`sendto()`向特定目标发送信息,并同样可以通过`recvfrom()`等待回应消息[^4]。 下面给出一段简单的Python代码示例用于演示如何实现基本的功能: #### Python 实现简单UDP Server/Client交互 ##### UDP Server (server.py) ```python import socket def udp_server(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定监听地址与端口 address = ('', 9090) server_socket.bind(address) while True: data, addr = server_socket.recvfrom(1024) print(f"Received message from {addr}: {data.decode('utf-8')}") if __name__ == '__main__': udp_server() ``` ##### UDP Client (client.py) ```python import socket def udp_client(server_ip='127.0.0.1'): client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) msg = 'Hello UDP' server_address = (server_ip, 9090) sent = client_socket.sendto(msg.encode(), server_address) response, _ = client_socket.recvfrom(1024) print(f'Received echo: {response.decode()}') if __name__ == '__main__': udp_client() ``` 上述例子展示了怎样构建一个简易的服务端与客户端模型来进行双向通讯。需要注意的是这里仅做基础功能展示,在真实环境中还需要考虑更多因素如错误处理机制等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值