一、介紹
有時候需要用windows写点小工具需要用到tcpip,这里介绍在dev c++下编写网络通信
流程和linux差不多
1、使用WSAStartup()函数检查系统协议栈安装情况
2、使用socket()函数创建服务器端通信套接字
3、使用bind()函数将创建的套接字与服务器地址绑定
4、使用listen()函数使服务器套接字做好接收连接请求准备
5、使用accept()接收来自客户端由connect()函数发出的连接请
6、根据连接请求建立连接后,使用send()函数发送数据,或者使7、用recv()函数接收数据
8、使用closesocket()函数关闭套接字(可以先用shutdown()函数9、先关闭读写通道)
10、最后调用WSACleanup()函数结束Winsock Sockets API
二、工程配置
添加库libws2_32.a
三、tcp 客户端
tcp.c
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
static SOCKET sClient;
#define CLENT_NUM 1
static SOCKET sSever,sSever_c[CLENT_NUM];
struct sockaddr_in sSever_c_sd[CLENT_NUM];
#define USER_ERROR -1
int tcp_client_init(char *ip, int iPort)
{
struct sockaddr_in ser; //服务器端地址
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("Failed to load Winsock.\n"); //Winsock 初始化错误
return -1;
}
ser.sin_family = AF_INET; //初始化服务器地址信息
ser.sin_port = htons(iPort); //端口转换为网络字节序
ser.sin_addr.s_addr = inet_addr(ip); //IP 地址转换为网络字节序
sClient = socket(AF_INET, SOCK_STREAM, 0); //创建客户端流式套接字
if (sClient == INVALID_SOCKET)
{
printf("socket() Failed: %d\n", WSAGetLastError());
return -1;
}
//请求与服务器端建立 TCP 连接
if (connect(sClient, (struct sockaddr *)&ser, sizeof(ser)) == INVALID_SOCKET)
{
printf("connect() Failed: %d\n", WSAGetLastError());
return -1;
}
printf("connect ok\n");
return 0;
}
int tcp_client_send(unsigned char *buff, int len)
{
send(sClient, buff, len, 0);
}
int tcp_client_rcv(unsigned char *buff, int *len)
{
int iLen; //从服务器端接收的数据长度
iLen = recv(sClient, buff, 1024, 0); //从服务器端接收数据
if (iLen == 0)
return -1;
else if (iLen == SOCKET_ERROR)
{
printf("recv() Failed: %d\n", WSAGetLastError());
return -1;
}
else
printf("recv() data from server: %s\n", buff); // 输出接收数据
*len = iLen;
return iLen;
}
int close_tcp_client()
{
closesocket(sClient); //关闭 socket
WSACleanup();
}
tcp.h
#ifndef __TCP_H
#define __TCP_H
int tcp_client_init(char *ip, int iPort);
int tcp_client_send(unsigned char *buff, int len);
int tcp_client_rcv(unsigned char *buff, int *len);
int close_tcp_client();
#endif
main.c
#include <stdio.h>
#include "tcp.h"
int tcp_client_test()
{
unsigned char buff[1024] = {0};
int rcv_len;
tcp_client_init("192.168.3.65", 1000);
while(1)
{
memset(buff, 0 , 1024);
rcv_len = tcp_client_rcv(buff, &rcv_len);
if(rcv_len > 0)
printf("rcv:%s\n", buff);
tcp_client_send(buff, rcv_len);
}
}
int main(int argc, char *argv[])
{
tcp_client_test();
return 0;
}
四、tcp服务端
tcp.c
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
#define CLENT_NUM 2
static SOCKET sSever,sSever_c[CLENT_NUM];
static SOCKET sSever_c1;
struct sockaddr_in sSever_c_sd[CLENT_NUM],sSever_c_sd1;
#define USER_ERROR -1
int ip_invalid(unsigned char *s)
{
if(s[0] == 0 && s[1] == 0
&&s[2] == 0 && s[3] == 0)
return 1;
else
return 0;
}
int tcp_server_init(int iPort)
{
struct sockaddr_in ser; //服务器端地址
WSADATA wsaData;
int i;
int addrlen;
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("Failed to load Winsock.\n");
return USER_ERROR;
}
ser.sin_family = AF_INET; //初始化服务器地址信息
ser.sin_port = htons(iPort); //端口转换为网络字节序
//ser.sin_addr.s_addr = htonl(INADDR_ANY);//
ser.sin_addr.s_addr = inet_addr("192.168.3.65");//
//ser.sin_addr.S_un.S_addr = INADDR_ANY;
sSever = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //创建客户端流式套接字
if(sSever == INVALID_SOCKET)
{
printf("socket() Failed: %d\n", WSAGetLastError());
return -1;
}
if(bind(sSever, (LPSOCKADDR)&ser, sizeof(ser)) == SOCKET_ERROR)
{
printf("blind() Failed:%d\n", WSAGetLastError());
return USER_ERROR;
}
if(listen(sSever, 5) == SOCKET_ERROR)
{
printf("listen() Failed:%d\n", WSAGetLastError());
return USER_ERROR;
}
addrlen = sizeof(struct sockaddr_in);
printf("create server ok\nip: %s,port:%d\n",inet_ntoa(ser.sin_addr), ntohs(ser.sin_port));
printf("wait link \n");
// sSever_c1 = accept(sSever, (SOCKADDR *)&sSever_c_sd1, &addrlen);
// printf("link a client ip:%s,port:%d\n",inet_ntoa(sSever_c_sd1.sin_addr),sSever_c_sd1.sin_port);
#if 1
for ( i = 0; i < CLENT_NUM; i++)
{
while(sSever_c[i] == INVALID_SOCKET)
{
sSever_c[i] = accept(sSever, (SOCKADDR *)&sSever_c_sd[i], &addrlen);
printf("error\n");
}
printf("link a client ip:%s,port:%d\n",inet_ntoa(sSever_c_sd[i].sin_addr),sSever_c_sd[i].sin_port);
}
#endif
printf("link ok\n");
return 0;
}
int tcp_server_send(char c, unsigned char *buff, int len)
{
send(sSever_c[c], buff, len, 0);
return 0;
}
int tcp_server_rcv(char c, unsigned char *buff, int *len)
{
int ret,i;
ret = recv(sSever_c[c], buff, 1024, 0);
*len = ret;
return ret;
}
int close_tcp_server()
{
closesocket(sSever);
WSACleanup();
}
tcp.h
#ifndef __TCP_H
#define __TCP_H
int tcp_server_init( int iPort);
int tcp_server_send(char c, unsigned char *buff, int len);
int tcp_server_rcv(char c, unsigned char *buff, int *len);
int close_tcp_server();
#endif
main.c
#include <stdio.h>
#include "tcp.h"
int tcp_server_test()
{
unsigned char buff[1024] = {0};
int rcv_len;
tcp_server_init(2000);
while(1)
{
memset(buff, 0 , 1024);
rcv_len = tcp_server_rcv(0, buff, &rcv_len);
if(rcv_len > 0)
{
printf("rcv:%s\n", buff);
tcp_server_send(0, buff, rcv_len);
}
}
}
int main(int argc, char *argv[])
{
tcp_server_test();
return 0;
}
结果:待更新