C语言基于socket-实现客户端-服务端通信

C语言基于socket-实现客户端-服务端通信

关于socket不多赘述,博主上一篇做过简单介绍,详情请自行百度查询,本次主要做的是基于socket通信的C语言实现

  1. 需要使用的头文件:
    winsock2.h
    操作平台Windows,使用编译器dev(报错缺的文件看文章末尾的补充)

  2. 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,已经定义好无需二次定义,博主给出仅供参考方便编程理解。

  1. 服务端代码实现
#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”–>勾选,保存

标题

效果演示
C语言基于socket-实现客户端-服务端通信
附上编译器生成的exe,需要的留邮箱。