windows环境下C语言套接字编程

  • Post author:
  • Post category:其他


此博客是对中科大计算机网络课程TCP和UDP套接字的实现,对客户端发送消息的大小写转换。PPT上的

sockadd_in



hostent

数据结构在

WinSock2.h

头文件里已经定义,如果不注释掉编译时会报redefine的错。由于使用的windows相关api所以编译时应指定链接的库。

gcc TCPClient.c -o TCPClint -lwsock32



TCP部分



客户端

#include<WinSock2.h>
#include<stdio.h>

//struct sockaddr_in
// {
//     u_short sin_family; //AF_INEF AF_INET(地址簇)PF_INET(协议簇)Internet(TCP/IP)
//     u_short sin_port;   //port    端口号
//     struct in_addr sin_addr;     
//         //Ip address unsigned long IP地址
//     char sin_zero[8];   //align   对齐长度
// };

// struct hostent
// {
//     char *h_name;       // 主机名
//     char **h_aliases;   // 主机别名
//     int h_addrtype;     // 主机IP地址类型 IPV4-AF_INET
//     int h_length;       //主机IP地址字节长度,对于IPv4是四字节
//     char **h_addr_list; //主机的IP地址列表  调用DNS域名解析后可能会放回多个IP地址 
//     #define h_addr h_addr_list[0]    //默认IP地址
// };

int main(int argc, char **argv)
{   
    /* 初始化环境, 选择2.2版本的套接字DLL*/
    WSADATA wd;
    WSAStartup(MAKEWORD(2,2),&wd);


    struct sockaddr_in sad; //	客户端信息
    struct hostent *ptrh;   //	客户端地址

    /* 缓冲区 */
    char Sentence[128];
    char modifiedSentence[128];

    /* 命令行传入主机名和端口号 */
    char *host = argv[1]; 
    int port = atoi(argv[2]);

    
    memset((char *)&sad, 0, sizeof(sad));   // 初始化客户端信息
    sad.sin_family = AF_INET;               // 设置服务端的网络协议IPv4
    ptrh = gethostbyname(host);             // 调用域名解析服务DNS,获得直击IP地址
    memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
                                            // 设置主机IP地址
    sad.sin_port = htons((u_short)port);    // 指定端口号

    /* 创建客户端句柄并和服务端连接*/
    int clientSocket;
    clientSocket = socket(PF_INET, SOCK_STREAM, 0); 
    connect(clientSocket, (struct sockaddr *)&sad, sizeof(sad));

    printf("请输入发送给客户端的内容 : ");
    gets(Sentence);
    send(clientSocket, Sentence, 128, 0);           //发送缓冲区内容
    recv(clientSocket, modifiedSentence, 128, 0);   //接受服务端发送的数据
    printf("服务端返回的数据为 : %s\n", modifiedSentence);


    closesocket(clientSocket);   //关闭连接
    WSACleanup();                //清理网络环境
    return 0;
}



服务端

#include <stdio.h>
#include <string.h>
#include <winsock2.h>

#define Sentence_LEN  128

int main(void)
{
	WSADATA wd;
    WSAStartup(MAKEWORD(2,2),&wd);  

	// SOCKET welcomeSocket, connectionSocket;  //整型变量 创建TCP句柄
	// SOCKADDR cad;
	// SOCKADDR_IN sad;

    int welcomeSocket, connectionSocket; 
    struct sockaddr_in sad;
    struct sockaddr_in cad;

    char Sentence[Sentence_LEN];
	int addr_size = 0, recv_len = 0;



	/* 创建服务端socket */
    welcomeSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	/* 设置服务端信息 */
    memset(&sad, 0, sizeof(sad)); 	            // 给结构体sad清零
    sad.sin_family = AF_INET;  					// 使用IPv4地址
    sad.sin_addr.s_addr = inet_addr("127.0.0.1");// 本机IP地址
    sad.sin_port = htons(12000);  				// 端口
	
	/* 绑定套接字 */
    bind(welcomeSocket, (SOCKADDR*)&sad, sizeof(SOCKADDR));
		
	/* 进入监听状态 */
    listen(welcomeSocket, 10);

	addr_size = sizeof(SOCKADDR);

	while (1)
	{
        printf("等待连接\n");
		/* 监听客户端请求,accept函数返回一个新的套接字,发送和接收都是用这个套接字 */
        connectionSocket = accept(welcomeSocket, (SOCKADDR*)&cad, &addr_size);

		/* 接受客户端的返回数据 */
		int recv_len = recv(connectionSocket, Sentence, Sentence_LEN, 0);
		printf("客户端发送过来的数据为:%s\n", Sentence);
		
        for(size_t i = 0; i < strlen(Sentence); i++)
            Sentence[i] = toupper(Sentence[i]);

		/* 发送数据到客户端 */
		send(connectionSocket, Sentence, recv_len, 0);
		
		/* 关闭客户端套接字 */
		closesocket(connectionSocket);
		
		/* 清空缓冲区 */
		memset(Sentence, 0, Sentence_LEN);  
	}


	//closesocket(welcomeSocket);
    //WSACleanup();

	return 0;
}



UDP



客户端

#include<stdio.h>
#include<WinSock2.h>

int main()
{
    WSADATA wd;
    WSAStartup(MAKEWORD(2, 2), &wd);

    #define MESSAGE_LEN 128
    char message[128];

    int clientSocket;
    
    struct sockaddr_in sad;
    int serveraddrLen = sizeof(sad);
    memset(&sad, 0, sizeof(sad));
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr("127.0.0.1");
    sad.sin_port = htons(12000);

    clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    printf("请输入发送到服务端的内容 : ");
    scanf("%s", message);
    sendto(clientSocket, message, MESSAGE_LEN, 0, (struct sockaddr *)&sad, sizeof(sad));
    

    recvfrom(clientSocket, message, MESSAGE_LEN, 0, (struct sockaddr *) &sad, &serveraddrLen);
    printf("服务端返回 : %s", message);

    closesocket(clientSocket);
    WSACleanup();
}



服务端

#include<WinSock2.h>
#include<string.h>
#include<stdio.h>

int main()
{
    WSADATA wd;
    WSAStartup(MAKEWORD(2, 2), &wd);

    int serverSocket;
    struct sockaddr_in sad;

    #define MESSAGE_LEN 128
    char message[MESSAGE_LEN];

    serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    memset(&sad, 0, sizeof(sad));
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr("127.0.0.1");
    sad.sin_port = htons(12000);

    bind(serverSocket, (struct sockaddr *)&sad, sizeof(sad));

    while(TRUE)
    {   
        printf("等待客户端连接\n");
        struct sockaddr_in cad;
        memset(&cad, 0, sizeof(cad));

        int clientAddrLen = sizeof(struct sockaddr);

        int ret = recvfrom(serverSocket, message, MESSAGE_LEN, 0, (struct sockaddr *)&cad, &clientAddrLen);

        printf("接受到客户端发送的 : %s\n", message);
        for(size_t i = 0; i < strlen(message); i++ )
            message[i] = toupper(message[i]);

        sendto(serverSocket, message, MESSAGE_LEN, 0, (struct sockaddr *)&cad, clientAddrLen);

        memset(message, 0, MESSAGE_LEN);
    } 

    return 0;
}



版权声明:本文为qq_54468377原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。