第一次学socket,惭愧,看了一些博客和项目代码写出来的小demo。
功能:
启动server端进程后,server端进入监听。
启动client端进程,用户输入字符串。
server端打印接收到的字符串,等待用户输入字符串,回复给client端。
client端打印接收到的字符串,demo结束。
server端代码:
#include <WinSock2.h> //for bind()
#include <stdio.h>
/* 长度 */
#define MAX_DATA_BUF_LEN (1024)
#define MAX_STR_IP_LEN (24)
/* 客户端端口和服务端端口*/
#define SERVER_PORT (12345)
#define CLIENT_PORT (12344)
/* 远端ip字符数组 */
char strRemoteIP[MAX_STR_IP_LEN] = { 0 };
void log(const char* str) {
printf("%s\n", str);
}
/* 初始化winsock */
int winSockInit() {
WSADATA wsaData;
int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (ret != 0) {
printf("WSAStartup failed: %d\n", ret);
WSACleanup();
return -1;
}
else {
/* 初始化成功则打印版本 */
printf("%s\n", wsaData.szDescription);
}
return 0;
}
/* 创建socket句柄,绑定到指定端口 */
int udpCreate(unsigned short port) {
if (0 != winSockInit()) {
return -1;
}
/* 创建socket:地址家族,socket类型,传输层协议 */
int socket_handle = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET == socket_handle) {
log("Invalid socket!");
return -1;
}
/* 绑定端口 */
struct sockaddr_in addr_info = { 0 };
addr_info.sin_family = AF_INET;
addr_info.sin_port = htons(port);
addr_info.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");
if (-1 == bind(socket_handle, (const struct sockaddr*)&addr_info, sizeof(addr_info))) {
log("bind error!");
return -1;
}
return socket_handle;
}
/* 从socket句柄接收消息 */
int udpRecv(int handle) {
log("waiting for msg...");
char data_buf[MAX_DATA_BUF_LEN] = { 0 };
struct sockaddr_in client_info = { 0 };
int name_len = sizeof(client_info);
/* 调用后进入阻塞 */
int ret = recvfrom(handle, data_buf, sizeof(data_buf), 0, (struct sockaddr*)&client_info, &name_len);
if (-1 == ret) {
log("recv error!");
return -1;
}
else {
/* 收到消息后保存远端ip */
char* ip_str = inet_ntoa(client_info.sin_addr);
memcpy(strRemoteIP, ip_str, strlen(ip_str));
printf("receive %d bytes from %s:%s\n", ret, strRemoteIP, data_buf);
}
return 0;
}
/* 向指定远端发送消息 */
int udpSend(int handle, const char* remoteIP, int port, char* data,int len) {
struct sockaddr_in client_info = { 0 };
client_info.sin_family = AF_INET;
client_info.sin_port = htons(port);
client_info.sin_addr.S_un.S_addr = inet_addr(remoteIP);
int name_len = sizeof(client_info);
int ret = sendto(handle, data, len, 0, (struct sockaddr*)&client_info, name_len);
if (-1 != ret) {
printf("successfully sent %d bytes.\n", ret);
}
else {
return -1;
}
return 0;
}
int main() {
int handle = udpCreate(SERVER_PORT);
if (-1 == handle) {
log("Invalid socket!");
return -1;
}
udpRecv(handle);
/* 获取输入*/
log("say something to the client:");
char data[MAX_DATA_BUF_LEN];
fgets(data, MAX_DATA_BUF_LEN, stdin);
/* 发送数据 */
udpSend(handle, strRemoteIP, CLIENT_PORT, data,strlen(data));
}
client端代码:
#include <WinSock2.h> //for bind()
#include <stdio.h>
/* 长度 */
#define MAX_DATA_BUF_LEN (1024)
#define MAX_STR_IP_LEN (24)
/* 客户端端口和服务端端口*/
#define SERVER_PORT (12345)
#define CLIENT_PORT (12344)
/* 远端ip字符数组 */
char strRemoteIP[MAX_STR_IP_LEN] = { 0 };
void log(const char* str) {
printf("%s\n", str);
}
/* 初始化winsock */
int winSockInit() {
WSADATA wsaData;
int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (ret != 0) {
printf("WSAStartup failed: %d\n", ret);
WSACleanup();
return -1;
}
else {
/* 初始化成功则打印版本 */
printf("%s\n", wsaData.szDescription);
}
return 0;
}
/* 创建socket句柄,绑定到指定端口 */
int udpCreate(unsigned short port) {
if (0 != winSockInit()) {
return -1;
}
/* 创建socket:地址家族,socket类型,传输层协议 */
int socket_handle = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET == socket_handle) {
log("Invalid socket!");
return -1;
}
/* 绑定端口 */
struct sockaddr_in addr_info = { 0 };
addr_info.sin_family = AF_INET;
addr_info.sin_port = htons(port);
addr_info.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");
if (-1 == bind(socket_handle, (const struct sockaddr*)&addr_info, sizeof(addr_info))) {
log("bind error!");
return -1;
}
return socket_handle;
}
/* 从socket句柄接收消息 */
int udpRecv(int handle) {
log("waiting for msg...");
char data_buf[MAX_DATA_BUF_LEN] = { 0 };
struct sockaddr_in client_info = { 0 };
int name_len = sizeof(client_info);
/* 调用后进入阻塞 */
int ret = recvfrom(handle, data_buf, sizeof(data_buf), 0, (struct sockaddr*)&client_info, &name_len);
if (-1 == ret) {
log("recv error!");
return -1;
}
else {
/* 收到消息后保存远端ip */
char* ip_str = inet_ntoa(client_info.sin_addr);
memcpy(strRemoteIP, ip_str, strlen(ip_str));
printf("receive %d bytes from %s:%s\n", ret, strRemoteIP, data_buf);
}
return 0;
}
/* 向指定远端发送消息 */
int udpSend(int handle, const char* remoteIP, int port, char* data,int len) {
struct sockaddr_in client_info = { 0 };
client_info.sin_family = AF_INET;
client_info.sin_port = htons(port);
client_info.sin_addr.S_un.S_addr = inet_addr(remoteIP);
int name_len = sizeof(client_info);
int ret = sendto(handle, data, len, 0, (struct sockaddr*)&client_info, name_len);
if (-1 != ret) {
printf("successfully sent %d bytes.\n", ret);
}
else {
return -1;
}
return 0;
}
int main() {
/* 创建套接字 */
int handle = udpCreate(CLIENT_PORT);
if (-1 == handle) {
log("Invalid socket!");
return -1;
}
/* 获取输入*/
log("say something to the server:");
char data[MAX_DATA_BUF_LEN];
fgets(data, MAX_DATA_BUF_LEN, stdin);
/* 发送数据 */
udpSend(handle, "127.0.0.1", SERVER_PORT, data,strlen(data));
/* 接收数据 */
udpRecv(handle);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。