码迷,mamicode.com
首页 > 编程语言 > 详细

windows网络编程-C语言实现简单的TCP协议聊天

时间:2017-11-24 20:14:20      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:ima   打电话   pre   api   win   clu   连接   ==   error:   

  TCP协议类似于打电话时,对方一定在手机附近并且此刻都在和对方进行通话。一定保证双方都在线,才能进行数据传输。UDP协议就像邮箱,不保证对方一定在等你邮件且对方不在你也可以给对方发送数据。实际上TCP协议、UDP协议,还有重要的TCP协议中的三次握手(建立连接)和四次挥手(关闭连接)等在网上也都解释得非常详细了,所以我就不多说了。

  Server端程序代码:

/*
 *	服务器端 Server.c
 *    
 */
#include <winsock2.h>
#include <stdio.h>

#define true 1
#define false 0

#define AF_INEF 2       //我用的VC++编写的,不知道为什么头文件中没有这个的定义,于是只能自己定义一个
#define BUFFSIZE 1024

int main(int argc, char**argv)
{
    int                Ret;
    WSADATA            wsaData;
    SOCKET            ListeningSocket;
    SOCKET            NewConnection;
    SOCKADDR_IN        ServerAddr;
    SOCKADDR_IN        ClientAddr;
    int                ClientAddrLen = sizeof(ClientAddr);
    unsigned short    Port = 5150;
    char            sendData[BUFFSIZE];
    char            recvData[BUFFSIZE];

    if((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
    {
        printf("WSASTARTUP_ERROR: %d\n", Ret);
        return false;
    }

    //创建一个套接字来监听客户机连接
    if((ListeningSocket = socket(AF_INEF, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
    {
        printf("SOCKET_ERROR: %d\n", INVALID_SOCKET);
        return false;
    }
    /*
     * 建立一个SOCKADDR_IN结构,这个结构将告知bind我们想要在5150端口
     * 监听所有接口上的连接
     */


    //将端口变量从主机字节顺序转换位网络字节顺序
    ServerAddr.sin_family = AF_INEF;
    ServerAddr.sin_port = htons(Port);
    ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

    //使用bind将这个地址信息和套接字绑定起来
    if(bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
    {
        printf("BIND_ERROR: %d\n", SOCKET_ERROR);
        return false;
    }

    //监听客户机连接。这里使用5个backlog
    if(listen(ListeningSocket, 5) == SOCKET_ERROR)
    {
        printf("LISTEN_ERROR: %d\n", SOCKET_ERROR);
        return false;
    }

    if((NewConnection = accept(ListeningSocket, (SOCKADDR *)&ClientAddr, &ClientAddrLen)) == INVALID_SOCKET)
    {
        printf("ACCPET_ERROR: %d\n", INVALID_SOCKET);
        closesocket(ListeningSocket);
        return false;
    }
    printf("检测到一个连接: %s 端口:%d\n", inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));

    //连接到达时,接受一个新连接
    while(true)
    {
        

        //接收数据
        Ret = recv(NewConnection, recvData, BUFFSIZE, 0);
        if(Ret > 0)
            printf("C.C.: %s\n", recvData);
        else if(Ret < 0)
            printf("RECV_ERROR: %d\n",  SOCKET_ERROR);
        else
        {
            printf("对方退出程序,聊天结束!");
            break;
        }

        printf("\n鲁鲁:");
        scanf("%s", &sendData);
        if(send(NewConnection, sendData, BUFFSIZE, 0) == SOCKET_ERROR)
        {
            printf("消息发送失败!\n");
            break;
        }
        

    }

    //完成新接受的连接后,用closesocket API关闭这些套接字
    closesocket(NewConnection);
    closesocket(ListeningSocket);

    //应用程序完成对接的处理后,调用WSACleanup
    if(WSACleanup() == SOCKET_ERROR)
    {
        printf("WSACLEANUP_ERROR: %d\n", WSAGetLastError());
        return false;
    }

    return 0;
}

  Client端程序代码:

/*
 *	客户端 Client.c
 *
 */
#include <winsock2.h>
#include <stdio.h>

#define true 1
#define false 0

#define AF_INEF 2
#define BUFFSIZE 1024

int main(int argc, char**argv)
{
	int				Ret;
	WSADATA			wsaData;
	SOCKET			s;
	SOCKADDR_IN		ServerAddr;
	unsigned short	Port = 5150;
	char			sendData[BUFFSIZE];
	char			recvData[BUFFSIZE];

	if((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
	{
		printf("WSASTARTUP_ERROR: %d\n", Ret);
		return false;
	}

	if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
	{
		printf("SOCKET_ERROR: %d\n", INVALID_SOCKET);
		return false;
	}

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(Port);
	ServerAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.102");  //这里以本机的IPV4地址测试

	if((connect(s, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr))) == SOCKET_ERROR)
	{
		printf("CONNECT_ERROR: %d\n", SOCKET_ERROR);
		closesocket(s);
		return false;
	}

	while(true)
	{
		printf("\nC.C.:");
		scanf("%s", &sendData);
		if(send(s, sendData, BUFFSIZE, 0) == SOCKET_ERROR)
		{
			printf("消息发送失败!\n");
			break;
		}

		Ret = recv(s, recvData, BUFFSIZE, 0);
		if(Ret > 0)
			printf("鲁鲁: %s\n", recvData);
		else if(Ret < 0)
			printf("RECV_ERROR: %d\n", SOCKET_ERROR);
		else
		{
			printf("对方退出程序,聊天结束!");
			break;
		}
	}

	closesocket(s);

	if(WSACleanup() == SOCKET_ERROR)
	{
		printf("WSACLEANUP_ERROR: %d\n", WSAGetLastError());
		return false;
	}

	return 0;
}

  运行结果:

技术分享图片

  emmm...对于所有可能出现的错误我都加上了会出错的函数名前缀,以便于找到错误。

  其他的书上解释得很详细,就不暴露自己水平了233...最后小小的感谢一下自己的学习~

 

windows网络编程-C语言实现简单的TCP协议聊天

标签:ima   打电话   pre   api   win   clu   连接   ==   error:   

原文地址:http://www.cnblogs.com/darkchii/p/7891942.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!