今天我们介绍如何在Windows下实现TCP通信,开发环境是Visual Stdio 2005
我们的程序很简单,客户端发送一个字符串给服务器,服务器返回这个字符串的大写形式,关于如何实现Windows下的UDP通信,请看这里:
http://blog.youkuaiyun.com/htttw/article/details/7596358
server.cpp:
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define SERVER_PORT 9153
void toUpper(char * in, char * out, int len)
{
int i;
char diff = 'a' - 'A';
for(i=0; i<len; ++i)
{
if( (in[i] >= 'a') && (in[i] <= 'z') )
{
out[i] = in[i] - diff;
}
else
{
out[i] = in[i];
}
}
}
int main()
{
/* init winsock */
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 1), &wsaData))
{
printf("winsock init failed\n");
return 1;
}
/* create a tcp socket */
SOCKET serverSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(serverSock <= 0)
{
printf("socket create failed\n");
return -1;
}
SOCKADDR_IN serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVER_PORT); /* 监听端口 */
serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); /* 本机 */
if(bind(serverSock, (SOCKADDR *)&serverAddr, sizeof(serverAddr)) != 0)
{
printf("bind failed\n");
return -1;
}
/* start listen */
printf("start listening...\n");
if(listen(serverSock, 1) != 0)
{
printf("listen failed\n");
return -1;
}
int len = sizeof(SOCKADDR_IN);
/* waiting for connection */
SOCKADDR_IN clientAddr;
SOCKET clientSock = accept(serverSock, (SOCKADDR *)&clientAddr, &len);
if(clientSock <= 0)
{
printf("accept failed\n");
return -1;
}
printf("connected\n");
char bufferIn[1024];
char bufferOut[1024];
while(1)
{
bufferIn[0] = '\0';
printf("waiting...\n");
if(recv(clientSock, bufferIn, sizeof(bufferIn), 0) <= 0)
{
/* error occurs */
printf("close connection\n");
break;
}
printf("got: %s", bufferIn);
toUpper(bufferIn, bufferOut, len);
if(send(clientSock, bufferOut, sizeof(bufferOut), 0)<=0)
{
printf("send error\n");
break;
}
}
closesocket(clientSock);
WSACleanup();
return 0;
}
client.cpp:
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define SERVER_ADDRESS "127.0.0.1"
#define SERVER_PORT 9153
int main()
{
/* init winsock */
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 1), &wsaData))
{
printf("winsock init failed\n");
return 1;
}
SOCKADDR_IN serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVER_PORT); /* 服务器监听端口 */
serverAddr.sin_addr.S_un.S_addr = inet_addr(SERVER_ADDRESS); /* 服务器地址 */
/* connect to server */
printf("connecting...\n");
/* create a tcp socket */
SOCKET sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock_fd <= 0)
{
printf("socket create failed\n");
return -1;
}
int len = sizeof(serverAddr);
if(connect(sock_fd, (SOCKADDR *)&serverAddr, len) != 0)
{
printf("connection failed\n");
return -1;
}
printf("connected\n");
char buffer[1024];
while(1)
{
printf("press: ");
fgets(buffer, sizeof(buffer), stdin);
/* send to server */
if(send(sock_fd, buffer, sizeof(buffer), 0) <= 0)
{
printf("send error\n");
break;
}
if(recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr *)&serverAddr, &len) != SOCKET_ERROR)
{
printf("got: %s", buffer);
}
}
WSACleanup();
return 0;
}
原理不多讲了,具体可以参考http://blog.youkuaiyun.com/htttw/article/details/7519964,虽然是Linux平台的,但原理类似。
截图: