把客戶端與服務器端分別放在兩個電腦上就無法通信了,為什么?求指點。。。
客戶端:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>
#define MAXSIZE 100
//參考外部函式時需要加上extern關鍵字,定義函式時默認均是extern
extern int getline(char *s, int max);
int main(int argc, char *argv[])
{
//初始化winsock結構,加載winsock動態庫
WSAData wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
printf("WSAStartup failed !\n");
return -1;
}
//創建套接字
SOCKET sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
printf("socket failed !\n");
return -1;
}
//初始化服務器地址結構
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9999);
servaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
//發起連接請求
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == SOCKET_ERROR) {
printf("connect failed !\n");
closesocket(sockfd);
WSACleanup();
return -1;
}
else
printf("Connection build...\n");
//向服務器發送資料
char buff[MAXSIZE];
memset(buff, 0 , MAXSIZE);
while (strcmp(buff, "quit") != 0 && strcmp(buff, "shutdown") != 0) {
printf("Please input a string to send: ");
getline(buff, MAXSIZE);
if(send(sockfd, buff, strlen(buff), 0) <= 0) {
printf("send failed !\n");
closesocket(sockfd);
WSACleanup();
return -1;
}
//初始化緩沖區為0
memset(buff, 0 , MAXSIZE);
if(recv(sockfd, buff, MAXSIZE, 0) <= 0) {
printf("recv failed !\n");
closesocket(sockfd);
WSACleanup();
return -1;
}
//列印收到的回顯字串
char msg[MAXSIZE];
memset(msg, 0 , MAXSIZE);
sprintf(msg, "Received from Server [%s:%d]: %s\n", inet_ntoa(servaddr.sin_addr), ntohs(servaddr.sin_port), buff);
printf("%s\n",msg);
}
//釋放資源
closesocket(sockfd);
WSACleanup();
system("pause");
return 0;
}
//getline函式定義:
int getline(char *s, int max)
{
int i = 0;
char c;
while (--max >0 && (c = getchar()) != EOF && c != '\n')
s[i++] = c;
if (c = '\n')
s[i] = '\0';
return i;
}
服務器端:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>
//添加默認鏈接庫
#pragma comment(lib, "ws2_32.lib")
#define bzero(a, b) memset(a, 0, b) //vc下沒有bzero的定義,用memset代替
// void *memset(void *dst, int c, size_t len)
DWORD WINAPI AnswerThread(LPVOID lparam); //執行緒函式宣告
struct sockaddr_in cliaddr; //定義外部變數供執行緒函式呼叫
int main( int argc, char *argv[])
{
//初始化winsock版本資訊,加載元件(dll)
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
printf("WSAStartup failed !\n");
return -1;
}
//創建監聽套接字
SOCKET sockfd;
if ( (sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ) == INVALID_SOCKET) {
printf("socket failed !\n");
WSACleanup();
return -1;
}
//設定服務器地址
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9999);
servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
//系結socket地址結構到監聽套接字
if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
printf("bind failed !\n");
closesocket(sockfd);
WSACleanup();
}
//在Server上進行監聽
if (listen(sockfd, 4) != 0) {
printf("listen failed !\n");
closesocket(sockfd);
WSACleanup();
return -1;
}
//接受客戶端的連接請求
printf("TCP Server Start...\n");
int cliaddrlen = sizeof(cliaddr); //cliaddrlen需要有初值,作為一個值-結果引數參與函式
bzero(&cliaddr, sizeof(cliaddr)); //memset(&cliaddr, 0, sizeof(cliaddr));
SOCKET connfd;
//回圈等待
while (true)
{
if ((connfd = accept(sockfd, (struct sockaddr *)&cliaddr, &cliaddrlen)) == INVALID_SOCKET) {
printf("accept failed !\n");
closesocket(sockfd);
WSACleanup();
return -1;
}
//創建新執行緒
DWORD ThreadID; //double word
CreateThread(NULL, 0, AnswerThread, (LPVOID)connfd, 0, &ThreadID);
}
}
//執行緒函式AnswerThread
DWORD WINAPI AnswerThread(LPVOID lparam)
{
//在Server和Client之間接收和發送資料
char buff[100];
extern sockaddr_in cliaddr;
SOCKET connfd = (SOCKET)(LPVOID)lparam;
while (true)
{
int ret = recv(connfd, buff, sizeof(buff), 0);
if (ret == SOCKET_ERROR) {
printf("recv failed !\n");
closesocket(connfd);
WSACleanup();
return -1;
}
//為了避免列印錯誤,將字串buff結尾設成0x00
buff[ret] = 0x00;
//獲取當前系統時間
SYSTEMTIME st;
GetLocalTime(&st);
char SysDate[30];
//將systime中的時間轉變為字串存入SysDate[30];
sprintf(SysDate, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
//Server顯示客戶端資訊
printf("%s Recv from Client [%s:%d] : %s\n", SysDate, inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buff);
//服務器向客戶端回顯資訊
//如果客戶端發送"quit"字串,則服務器退出
if (strcmp(buff, "quit") == 0) {
send(connfd, "quit", strlen("quit"), 0);
break;
}
//否則向客戶端回顯字串
else if (strcmp(buff, "shutdown") == 0) {
send(connfd, "shutdown server", strlen("shutdown server"), 0);
printf("Server is shutdowning...\n");
WSACleanup();
system("pause");
break;
}
else
{
char msg[100];
sprintf(msg, "Message Received : %s", buff);
if (send(connfd, msg, strlen(msg), 0) == SOCKET_ERROR) {
printf("send failed !\n");
closesocket(connfd);
return -1;
}
}
}
//釋放資源
closesocket(connfd);
}
uj5u.com熱心網友回復:
http://download.csdn.net/detail/kwer/9064301uj5u.com熱心網友回復:
如果本機通訊沒有問題,分開在兩個機器上,請檢查服務器程式所在機器的防火墻,先關掉防火墻試試可不可以通訊。uj5u.com熱心網友回復:
servaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/80085.html
標籤:網絡及通訊開發
