天天看點

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,需要的留郵箱。

繼續閱讀