#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define UM_SOCK WM_USER+100
#define MAX_ERROR_TEXT 64
#define BUFFER_LENGTH 1024
#define ServerName "127.0.0.1"
#define UserPort 6666
/*客户程序
我在Project-》settings-》link-》Object/library modules 中加入了 WS2_32.LIB WSOCK32.LIB 但是连接是出现
Compiling...
client.cpp
Linking...
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/client.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
*/#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
#endif#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>SOCKET Sockets; // 套接字描述符
HWND GlobalhWindow;
char EchoClassStr[] = "WS2EchoClient";
char sbuf[BUFFER_LENGTH], rbuf[BUFFER_LENGTH]; // 发送/接收缓冲区
DWORD TotalByteSent; // 总的发送字节数
WSABUF SendBuf, RecvBuf; // 发送/接收缓冲区结构BOOL InitWindow(HINSTANCE InstanceHandle,HINSTANCE PrevInstanceHandle);
void DisplayInfo(HWND hWnd, WSABUF * lpBuffer);
void CALLBACK SendCompFunc( DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD Flags);
int DoOverlappedCallbackSend(SOCKET Socket,LPWSABUF Buffers);
int DoRecv(SOCKET Socket, LPWSABUF lpRecvBuffer);
BOOL MakeConnection(void);
BOOL InitWS2(void);
LRESULT CALLBACK MainWndProc(HWND WindowHandle,UINT Message,WPARAM WParam,LPARAM LParam);
int APIENTRY WinMain(HINSTANCE InstanceHandle,
HINSTANCE PrevInstanceHandle,
LPSTR CmdLine,
int CmdShow)
{
MSG Message;
if (!InitWindow(InstanceHandle, PrevInstanceHandle)) {
MessageBox(NULL, "Couldn't Initialize Echo!", "Error",
MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
return(0);
}
GlobalhWindow = CreateWindow(EchoClassStr, "WinSock 2 Echo Client",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, InstanceHandle, NULL);
if (GlobalhWindow == NULL) {
MessageBox(NULL, "CreateWindow()!", "Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
return(0);
}
if (!InitWS2()) // 启动WinSock 2.
return(0);
if (!MakeConnection()) // 与服务器建立连接
return(0);
ShowWindow(GlobalhWindow, CmdShow);
UpdateWindow(GlobalhWindow);
while (GetMessage(&Message, NULL, 0, 0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
WSACleanup(); // 收到WM_QUIT消息后,结束WinSock 2.
return(Message.wParam);
} // WinMain()LRESULT CALLBACK MainWndProc(
HWND WindowHandle,
UINT Message,
WPARAM WParam,
LPARAM LParam)
{
int retcode;
char MsgText[128];
switch (Message) {
case UM_SOCK:
switch (LParam) {
case FD_CONNECT: //连接建立完成,置标志。
WSAAsyncSelect(Sockets, GlobalhWindow, UM_SOCK, FD_READ);
break;
case FD_READ: //数据读准备好,接收网络数据。
retcode = DoRecv(Sockets, &RecvBuf);
if (retcode == 1)
DisplayInfo(WindowHandle, &RecvBuf);
break;
case FD_WRITE: //写准备好,发送数据。
retcode = DoOverlappedCallbackSend(Sockets, &SendBuf);
SendBuf.len = 0;
break;
case FD_CLOSE: //连接关闭。
closesocket(Sockets);
break;
default:
if (WSAGETSELECTERROR(LParam) != 0) {
sprintf(MsgText, "Client: LParam=%d",WSAGETSELECTERROR(LParam));
MessageBox(GlobalhWindow, MsgText,
"Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
closesocket(Sockets);
}
break;
}
break;
case WM_CHAR:
if (WParam == 0x0d) // 用户键入回车键则发送一行。
PostMessage(GlobalhWindow, UM_SOCK, (WPARAM) WParam, (LPARAM)FD_WRITE);
else
SendBuf.buf[SendBuf.len++] = (char)WParam;
break;
case WM_DESTROY: // 关闭监听套接字并退出应用程序
closesocket(Sockets);
PostQuitMessage(0);
break;
default:
return (DefWindowProc(WindowHandle, Message, WParam, LParam));
} // switch(Message)
return (0);
} // MainWndProc()
/* * 启动WinSock 2,协商WinSock版本号,初始化接收发送缓冲区。 * 成功返回TRUE,失败返回FALSE。 */BOOL InitWS2(void)
{
int Error; // catches return value of WSAStartup
WORD VersionRequested; // passed to WSAStartup
WSADATA WsaData; // receives data from WSAStartup
BOOL ReturnValue = TRUE; // return value
VersionRequested = MAKEWORD(VERSION_MAJOR, VERSION_MINOR);
Error = WSAStartup(VersionRequested, &WsaData); // 启动WinSock 2
if (Error) {
MessageBox(GlobalhWindow, "Could not find high enough version of WinSock",
"Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
ReturnValue = FALSE;
} else {// 确认WinSock 2 DLL支持我们需要的精确版本号,否则,调用WSACleanup()。
if (LOBYTE(WsaData.wVersion) != VERSION_MAJOR
|| HIBYTE(WsaData.wVersion) != VERSION_MINOR) {
MessageBox(GlobalhWindow, "Could not find the correct version of WinSock",
"Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
WSACleanup();
ReturnValue = FALSE;
}
}
SendBuf.len = RecvBuf.len = 0; // 初始化接收/发送缓冲区。
SendBuf.buf = sbuf;
RecvBuf.buf = rbuf;
return(ReturnValue);
} // InitWS2()
#define VERSION_MINOR 0
#define UM_SOCK WM_USER+100
#define MAX_ERROR_TEXT 64
#define BUFFER_LENGTH 1024
#define ServerName "127.0.0.1"
#define UserPort 6666
/*客户程序
我在Project-》settings-》link-》Object/library modules 中加入了 WS2_32.LIB WSOCK32.LIB 但是连接是出现
Compiling...
client.cpp
Linking...
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/client.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
*/#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
#endif#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>SOCKET Sockets; // 套接字描述符
HWND GlobalhWindow;
char EchoClassStr[] = "WS2EchoClient";
char sbuf[BUFFER_LENGTH], rbuf[BUFFER_LENGTH]; // 发送/接收缓冲区
DWORD TotalByteSent; // 总的发送字节数
WSABUF SendBuf, RecvBuf; // 发送/接收缓冲区结构BOOL InitWindow(HINSTANCE InstanceHandle,HINSTANCE PrevInstanceHandle);
void DisplayInfo(HWND hWnd, WSABUF * lpBuffer);
void CALLBACK SendCompFunc( DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD Flags);
int DoOverlappedCallbackSend(SOCKET Socket,LPWSABUF Buffers);
int DoRecv(SOCKET Socket, LPWSABUF lpRecvBuffer);
BOOL MakeConnection(void);
BOOL InitWS2(void);
LRESULT CALLBACK MainWndProc(HWND WindowHandle,UINT Message,WPARAM WParam,LPARAM LParam);
int APIENTRY WinMain(HINSTANCE InstanceHandle,
HINSTANCE PrevInstanceHandle,
LPSTR CmdLine,
int CmdShow)
{
MSG Message;
if (!InitWindow(InstanceHandle, PrevInstanceHandle)) {
MessageBox(NULL, "Couldn't Initialize Echo!", "Error",
MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
return(0);
}
GlobalhWindow = CreateWindow(EchoClassStr, "WinSock 2 Echo Client",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, InstanceHandle, NULL);
if (GlobalhWindow == NULL) {
MessageBox(NULL, "CreateWindow()!", "Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
return(0);
}
if (!InitWS2()) // 启动WinSock 2.
return(0);
if (!MakeConnection()) // 与服务器建立连接
return(0);
ShowWindow(GlobalhWindow, CmdShow);
UpdateWindow(GlobalhWindow);
while (GetMessage(&Message, NULL, 0, 0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
WSACleanup(); // 收到WM_QUIT消息后,结束WinSock 2.
return(Message.wParam);
} // WinMain()LRESULT CALLBACK MainWndProc(
HWND WindowHandle,
UINT Message,
WPARAM WParam,
LPARAM LParam)
{
int retcode;
char MsgText[128];
switch (Message) {
case UM_SOCK:
switch (LParam) {
case FD_CONNECT: //连接建立完成,置标志。
WSAAsyncSelect(Sockets, GlobalhWindow, UM_SOCK, FD_READ);
break;
case FD_READ: //数据读准备好,接收网络数据。
retcode = DoRecv(Sockets, &RecvBuf);
if (retcode == 1)
DisplayInfo(WindowHandle, &RecvBuf);
break;
case FD_WRITE: //写准备好,发送数据。
retcode = DoOverlappedCallbackSend(Sockets, &SendBuf);
SendBuf.len = 0;
break;
case FD_CLOSE: //连接关闭。
closesocket(Sockets);
break;
default:
if (WSAGETSELECTERROR(LParam) != 0) {
sprintf(MsgText, "Client: LParam=%d",WSAGETSELECTERROR(LParam));
MessageBox(GlobalhWindow, MsgText,
"Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
closesocket(Sockets);
}
break;
}
break;
case WM_CHAR:
if (WParam == 0x0d) // 用户键入回车键则发送一行。
PostMessage(GlobalhWindow, UM_SOCK, (WPARAM) WParam, (LPARAM)FD_WRITE);
else
SendBuf.buf[SendBuf.len++] = (char)WParam;
break;
case WM_DESTROY: // 关闭监听套接字并退出应用程序
closesocket(Sockets);
PostQuitMessage(0);
break;
default:
return (DefWindowProc(WindowHandle, Message, WParam, LParam));
} // switch(Message)
return (0);
} // MainWndProc()
/* * 启动WinSock 2,协商WinSock版本号,初始化接收发送缓冲区。 * 成功返回TRUE,失败返回FALSE。 */BOOL InitWS2(void)
{
int Error; // catches return value of WSAStartup
WORD VersionRequested; // passed to WSAStartup
WSADATA WsaData; // receives data from WSAStartup
BOOL ReturnValue = TRUE; // return value
VersionRequested = MAKEWORD(VERSION_MAJOR, VERSION_MINOR);
Error = WSAStartup(VersionRequested, &WsaData); // 启动WinSock 2
if (Error) {
MessageBox(GlobalhWindow, "Could not find high enough version of WinSock",
"Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
ReturnValue = FALSE;
} else {// 确认WinSock 2 DLL支持我们需要的精确版本号,否则,调用WSACleanup()。
if (LOBYTE(WsaData.wVersion) != VERSION_MAJOR
|| HIBYTE(WsaData.wVersion) != VERSION_MINOR) {
MessageBox(GlobalhWindow, "Could not find the correct version of WinSock",
"Error", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
WSACleanup();
ReturnValue = FALSE;
}
}
SendBuf.len = RecvBuf.len = 0; // 初始化接收/发送缓冲区。
SendBuf.buf = sbuf;
RecvBuf.buf = rbuf;
return(ReturnValue);
} // InitWS2()
解决方案 »
- COM组件的QueryInterface问题
- 难道VS2010编写出来文件都要.NET包??
- activex中对象的创建
- 如何在内存入写入超过原有字符串长度的数据
- 高手请指教:如何得到DLL的文件名
- 求教关于com的类型转化!
- HDC 的一个问题!
- 如何设置静态文本控件透明? 如vfp,vb里的,透明后可将两个控件重叠实现立体效果
- SetDIBitsToDevice的问题
- 谁知道金山词霸的单词库格式?或者谁有免费的单词库?
- 我需要把我已经改变了的HTML内容保存下来。我用了IHTMLDocument2->execCommand()方法。如何是SaveAs象Save一样不弹出SaveAs对话框?
- 一个程序流程的问题
BOOL MakeConnection(void)
{
int ConnectStatus; // the return value of WSAConnect
int Error; // gets error values
BOOL ReturnValue; // holds the return value
struct sockaddr_in SockAddr; // socket address for WSAConnect
int SockAddrLen; // the length of the above
CHAR MsgText[MAX_ERROR_TEXT];
Sockets = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
if (Sockets == INVALID_SOCKET) {
sprintf(MsgText, "Could not open a socket. [%d]", WSAGetLastError());
MessageBox(GlobalhWindow, MsgText, "Non-fatal error.", MB_OK | MB_SETFOREGROUND);
return(FALSE);
}
WSAAsyncSelect(Sockets, GlobalhWindow, UM_SOCK, FD_CONNECT); // 设置连接建立的事件通知
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(UserPort);
SockAddr.sin_addr.s_addr = inet_addr(ServerName);
SockAddrLen = sizeof(SockAddr);
// 和远程服务器建立连接。
ConnectStatus = WSAConnect(Sockets, (struct sockaddr *)&SockAddr, SockAddrLen,
NULL, NULL, NULL, NULL);
if (ConnectStatus == SOCKET_ERROR) {
Error = WSAGetLastError();
if (Error != WSAEWOULDBLOCK) { // 错误WSAEWOULDBLOCK意味着连接稍后建立
wsprintf(MsgText, "WSAConnect failed. Error code: %d", Error);
MessageBox(GlobalhWindow, MsgText, "Error",
MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
ReturnValue = FALSE;
}
}
return(ReturnValue);
} // MakeConnection()
/*
* 接收数据。
*/
int DoRecv(SOCKET Socket, LPWSABUF lpRecvBuffer)
{
DWORD NumBytes; // stores how many bytes we received
int Error; // gets error values
int Result; // gets return value from WSARecv
DWORD Flags=0; // flags for WSARecv
int ReturnValue = 1; // returnValue
lpRecvBuffer->len = BUFFER_LENGTH - 1;
Result = WSARecv(Socket, lpRecvBuffer, 1, &NumBytes, &Flags, NULL, NULL); // 接收数据
if (Result == SOCKET_ERROR) {
Error = WSAGetLastError();
switch (Error) {
case WSAENETRESET:
case WSAECONNRESET:
ReturnValue = -1; // 连接被重置
break;
case WSAEWOULDBLOCK: // 没有数据可供读取
ReturnValue = 0;
break;
default: // 其它错误
ReturnValue = -2;
break;
}
}
lpRecvBuffer->len = NumBytes;
return(ReturnValue);
} // DoRecv()
/*
* 使用回调函数的重叠发送方式发送数据。
*/
int DoOverlappedCallbackSend(
SOCKET Socket,
LPWSABUF Buffers)
{
int Size = 0; // how many bytes we send
int Error; // return value of WSASend
int Errno; // result of WSAGetLastError
DWORD BytesSent; // needed in WSASend
int ReturnValue = 1; // the return value
WSAOVERLAPPED Overlapped;
// 发送数据。完成例程设置为函数SendCompFunc()。
Error = WSASend(Socket, Buffers, 1, &BytesSent, 0, &Overlapped, SendCompFunc);
if (Error == SOCKET_ERROR) {
Errno = WSAGetLastError();
if (Errno == WSAEWOULDBLOCK)
// WSAEWOULDBLOCK意味着必须等待FD_WRITE事件才能发送
ReturnValue = 0;
else if (Errno == WSA_IO_PENDING) // 重叠操作成功初始化
ReturnValue = 1;
else // 其它错误
ReturnValue = -1;
}
// 如果没有错误,意味着发送操作立即完成。
return(ReturnValue);
} // DoOverlappedCallbackSend()
/*
* 完成例程在已成功初始化的重叠操作完成时被调用。它用来统计发送的字节数。
* 参数:
* Error -- 提供重叠操作的完成状态。
* BytesTransferred -- 提供实际发送的字节数。
* Overlapped -- 提供一个指向WSAOVERLAPPED结构的指针,其hEvent域可以用来
* 给完成例程传递上下文信息。
* Flags -- 未用。
*/
void CALLBACK SendCompFunc(
DWORD Error,
DWORD BytesTransferred,
LPWSAOVERLAPPED Overlapped,
DWORD Flags)
{
TotalByteSent += BytesTransferred; // 统计发送字节数。
if (Error)
MessageBox(NULL, "Error during overlapped send.", "Error", MB_OK | MB_SETFOREGROUND);
} // SendCompFunc()
void DisplayInfo(HWND hWnd, WSABUF * lpBuffer)//显示接收数据子程序。
{
HDC dc;
int l;
char line[128];
static int row = 0;
lpBuffer->buf[lpBuffer->len] = 0;
if (dc = GetDC(hWnd)) {
l = wsprintf((LPSTR) line, "%s",lpBuffer->buf);
TextOut(dc, 10, 16*row, (LPSTR) line, lpBuffer->len);
ReleaseDC(hWnd, dc);
}
row ++;
}BOOL InitWindow(
HINSTANCE InstanceHandle,
HINSTANCE PrevInstanceHandle)
{
WNDCLASS WndClass; // window class structure
if (!PrevInstanceHandle) {
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = MainWndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = InstanceHandle;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = EchoClassStr;
if (!RegisterClass(&WndClass))
return(FALSE);
}
return(TRUE);
}
错误信息是没有main函数。有可能你创建的工程和代码原来的工程类型不同!比如说原来的工程Win32 Application,但你新建一个Console的工程,直接拷过来的代码有时候是不能直接用的,要做些改变。
ws2_32.lib是winsock2,wsock32.lib可以看作是winsock1