C語言基于socket-實作用戶端-服務端通信
關于socket不多贅述,部落客上一篇做過簡單介紹,詳情請自行百度查詢,本次主要做的是基于socket通信的C語言實作
-
需要使用的頭檔案:
winsock2.h
操作平台Windows,使用編譯器dev(報錯缺的檔案看文章末尾的補充)
-
winsock2中資料結構及調用簡單說明:
socket的建立使用SOCKET,
socket的的位址空間建立采用socketaddr_in
bind()服務端用來綁定端口
listen()偵聽模式
accept()接受服務
send()發送資料
recv()接收資料
connect()用戶端連接配接伺服器
socketaddr_in的資料結構如下:
/*struct sockaddr
{
//位址族,2位元組
unsigned short sa_family;
//存放位址和端口,14位元組
char S_un.S_addr[14];
}
struct sockaddr_in
{
//位址族
short int sin_family;
//端口号(使用網絡位元組序)
unsigned short int sin_port;
//位址
struct in_addr sin_addr;
}
*/
該資料winsock2,已經定義好無需二次定義,部落客給出僅供參考友善程式設計了解。
- 服務端代碼實作
#include <stdio.h>
#include <winsock2.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
//初始化
WSADATA wsa_data;
if(WSAStartup(0x202, &wsa_data)!=0)
{
return 0;
}
//建立套接字
SOCKET server_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(server_listen == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}
//綁定IP和端口
sockaddr_in server_socket;
server_socket.sin_family = AF_INET;
server_socket.sin_port = htons(8888);
server_socket.sin_addr.S_un.S_addr = INADDR_ANY;
if(bind(server_listen, (LPSOCKADDR)&server_socket, sizeof(server_socket)) == SOCKET_ERROR)
{
printf("bind error !");
}
//開始監聽
if(listen(server_listen, 5) == SOCKET_ERROR)
{
printf("listen error !");
}
//建立用戶端套接字
SOCKET client_socket;
sockaddr_in client_addr;
int client_addr_len = sizeof(client_addr);
char rev_data[255];
//循環接收資料
while (true)
{
printf("\nWait connect...\n");
client_socket = accept(server_listen, (SOCKADDR *)&client_addr, &client_addr_len);
if(client_socket == INVALID_SOCKET)
{
printf("accept error !");
continue;
}
printf("\nClient IP: %s\n", inet_ntoa(client_addr.sin_addr));
//接收資料
int ret = recv(client_socket, rev_data, 255, 0);
if(ret)
{
rev_data[ret] = '\0';
printf(rev_data);
}
//回送資料
const char * send_data = "Hello! TCP_CLIENT!\n";
send(client_socket, send_data, strlen(send_data), 0);
//關閉套接字
closesocket(client_socket);
}
//關閉偵聽套接字
closesocket(server_listen);
//關閉初始化服務
WSACleanup();
return 0;
}
4.用戶端代碼實作
#include <stdio.h>
#include <winsock2.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
//初始化
WSADATA wsa_data;
if(WSAStartup(0x202, &wsa_data)!=0)
{
return 0;
}
//建立套接字
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(client_socket == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}
//綁定IP和端口
sockaddr_in server_socket;
server_socket.sin_family = AF_INET;
server_socket.sin_port = htons(8888);
server_socket.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if(connect(client_socket, (LPSOCKADDR)&server_socket, sizeof(server_socket)) == SOCKET_ERROR)
{
printf("conect error !");
return 1;
}
printf("connect suceessfully\n");
char send_buff[255];
char rec_buff[255];
while(true)
{
printf("input message:");
scanf("%s",send_buff);
send(client_socket,send_buff,sizeof(send_buff),0);
if (strcmp(send_buff,"exit")==0) break;
rec_buff[0] = '\0';
int data_len = recv(client_socket,rec_buff,255,0);
rec_buff[data_len]='\0';
printf("\n%s\n",rec_buff);
}
closesocket(client_socket);
WSACleanup();
return 0;
}
補充
dev直接運作會報錯
需要手動添加配置檔案:
“工具”–>“編譯選項”–>“編譯器”–>添加“-lwsock32”–>勾選,儲存
标題
效果示範

附上編譯器生成的exe,需要的留郵箱。