第一次學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);
}